revert yang2cli sub code, use existing yang2cli solution
This commit is contained in:
parent
dda3244252
commit
75f85e0253
15 changed files with 339 additions and 191 deletions
|
|
@ -63,8 +63,6 @@ Developers may need to change their code
|
||||||
|
|
||||||
### Minor changes
|
### Minor changes
|
||||||
|
|
||||||
* Auto-cli: create generated CLI for sub-parts of a YANG spec
|
|
||||||
* Experimental, see `yang2cli_sub()`
|
|
||||||
* Improved performance of parsing files as described in [Bytewise read() of files is slow #146](https://github.com/clicon/clixon/issues/146), thanks: @hjelmeland
|
* Improved performance of parsing files as described in [Bytewise read() of files is slow #146](https://github.com/clicon/clixon/issues/146), thanks: @hjelmeland
|
||||||
* Added new backend plugin: ca_pre-demon called if backend is daemonized just prior to forking.
|
* Added new backend plugin: ca_pre-demon called if backend is daemonized just prior to forking.
|
||||||
* Added XPATH functions `position`
|
* Added XPATH functions `position`
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
* Autocli mode support
|
* Autocli mode support
|
||||||
|
* The code uses two variables saved in the clixon handle and accessed via clicon_data_cvec_get,set:
|
||||||
|
* cli-edit-mode - This is the api-path of the current cli mode in the loaded yang context
|
||||||
|
* cli-edit-cvv - These are the assigned cligen list of variables with values at the edit-mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
|
@ -124,7 +127,8 @@ cvec_append(cvec *cvv0,
|
||||||
* Format of argv:
|
* Format of argv:
|
||||||
* <api_path_fmt> Generated API PATH (This is where we are in the tree)
|
* <api_path_fmt> Generated API PATH (This is where we are in the tree)
|
||||||
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
||||||
* <dbname> "running"|"candidate"|"startup"y
|
* Note api_path_fmt is not used in code but must be there in order to pick coorig from matching
|
||||||
|
* code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cli_auto_edit(clicon_handle h,
|
cli_auto_edit(clicon_handle h,
|
||||||
|
|
@ -139,17 +143,21 @@ cli_auto_edit(clicon_handle h,
|
||||||
pt_head *ph;
|
pt_head *ph;
|
||||||
cg_obj *co;
|
cg_obj *co;
|
||||||
cg_obj *coorig;
|
cg_obj *coorig;
|
||||||
cligen_handle ch;
|
|
||||||
cvec *cvv2 = NULL; /* cvv2 = cvv0 + cvv1 */
|
cvec *cvv2 = NULL; /* cvv2 = cvv0 + cvv1 */
|
||||||
|
|
||||||
|
if (cvec_len(argv) != 2){
|
||||||
|
clicon_err(OE_PLUGIN, EINVAL, "Usage: %s(api_path_fmt>, <treename>)", __FUNCTION__);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
cv = cvec_i(argv, 1);
|
cv = cvec_i(argv, 1);
|
||||||
treename = cv_string_get(cv);
|
treename = cv_string_get(cv);
|
||||||
ch = cli_cligen(h);
|
/* Find current cligen tree */
|
||||||
if ((ph = cligen_ph_find(cli_cligen(h), treename)) == NULL){
|
if ((ph = cligen_ph_find(cli_cligen(h), treename)) == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "No such parsetree header: %s", treename);
|
clicon_err(OE_PLUGIN, 0, "No such parsetree header: %s", treename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((co = cligen_co_match(ch)) != NULL &&
|
/* Find the matching cligen object */
|
||||||
|
if ((co = cligen_co_match(cli_cligen(h))) != NULL &&
|
||||||
(coorig = co->co_treeref_orig) != NULL)
|
(coorig = co->co_treeref_orig) != NULL)
|
||||||
cligen_ph_workpoint_set(ph, coorig);
|
cligen_ph_workpoint_set(ph, coorig);
|
||||||
else{
|
else{
|
||||||
|
|
@ -158,7 +166,7 @@ cli_auto_edit(clicon_handle h,
|
||||||
}
|
}
|
||||||
if ((cvv2 = cvec_append(clicon_data_cvec_get(h, "cli-edit-cvv"), cvv1)) == NULL)
|
if ((cvv2 = cvec_append(clicon_data_cvec_get(h, "cli-edit-cvv"), cvv1)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
/* First argv argument: API_path format */
|
/* API_path format */
|
||||||
if ((api_path_fmt = co2apipath(coorig)) == NULL){
|
if ((api_path_fmt = co2apipath(coorig)) == NULL){
|
||||||
clicon_err(OE_YANG, EINVAL, "No apipath found");
|
clicon_err(OE_YANG, EINVAL, "No apipath found");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -167,7 +175,8 @@ cli_auto_edit(clicon_handle h,
|
||||||
if (api_path_fmt2api_path(api_path_fmt, cvv2, &api_path) < 0)
|
if (api_path_fmt2api_path(api_path_fmt, cvv2, &api_path) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Store this as edit-mode */
|
/* Store this as edit-mode */
|
||||||
clicon_data_set(h, "cli-edit-mode", api_path);
|
if (clicon_data_set(h, "cli-edit-mode", api_path) < 0)
|
||||||
|
goto done;
|
||||||
if (clicon_data_cvec_set(h, "cli-edit-cvv", cvv2) < 0)
|
if (clicon_data_cvec_set(h, "cli-edit-cvv", cvv2) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -183,7 +192,6 @@ cli_auto_edit(clicon_handle h,
|
||||||
* @param[in] argv Vector oif user-supplied keywords
|
* @param[in] argv Vector oif user-supplied keywords
|
||||||
* Format of argv:
|
* Format of argv:
|
||||||
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
||||||
* <dbname> "running"|"candidate"|"startup"
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cli_auto_up(clicon_handle h,
|
cli_auto_up(clicon_handle h,
|
||||||
|
|
@ -204,6 +212,10 @@ cli_auto_up(clicon_handle h,
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
if (cvec_len(argv) != 1){
|
||||||
|
clicon_err(OE_PLUGIN, EINVAL, "Usage: %s(<treename>)", __FUNCTION__);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
treename = cv_string_get(cv);
|
treename = cv_string_get(cv);
|
||||||
if ((ph = cligen_ph_find(cli_cligen(h), treename)) == NULL){
|
if ((ph = cligen_ph_find(cli_cligen(h), treename)) == NULL){
|
||||||
|
|
@ -254,10 +266,9 @@ cli_auto_up(clicon_handle h,
|
||||||
/*! CLI callback: Working point tree reset to top level
|
/*! CLI callback: Working point tree reset to top level
|
||||||
* @param[in] h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param[in] cvv Vector of variables from CLIgen command-line
|
* @param[in] cvv Vector of variables from CLIgen command-line
|
||||||
* @param[in] argv Vector oif user-supplied keywords
|
* @param[in] argv Vector of user-supplied keywords
|
||||||
* Format of argv:
|
* Format of argv:
|
||||||
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
||||||
* <dbname> "running"|"candidate"|"startup"
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cli_auto_top(clicon_handle h,
|
cli_auto_top(clicon_handle h,
|
||||||
|
|
@ -268,7 +279,6 @@ cli_auto_top(clicon_handle h,
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
char *treename;
|
char *treename;
|
||||||
pt_head *ph;
|
pt_head *ph;
|
||||||
cvec *cvv0 = NULL;
|
|
||||||
|
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
treename = cv_string_get(cv);
|
treename = cv_string_get(cv);
|
||||||
|
|
@ -279,8 +289,8 @@ cli_auto_top(clicon_handle h,
|
||||||
cligen_ph_workpoint_set(ph, NULL);
|
cligen_ph_workpoint_set(ph, NULL);
|
||||||
/* Store this as edit-mode */
|
/* Store this as edit-mode */
|
||||||
clicon_data_set(h, "cli-edit-mode", "");
|
clicon_data_set(h, "cli-edit-mode", "");
|
||||||
if ((cvv0 = clicon_data_cvec_get(h, "cli-edit-cvv")) != NULL)
|
if (clicon_data_cvec_get(h, "cli-edit-cvv") != NULL)
|
||||||
clicon_data_del(h, "cli_edit-cvv");
|
clicon_data_del(h, "cli-edit-cvv");
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -289,7 +299,7 @@ cli_auto_top(clicon_handle h,
|
||||||
/*! CLI callback: Working point tree show
|
/*! CLI callback: Working point tree show
|
||||||
* @param[in] h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param[in] cvv Vector of variables from CLIgen command-line
|
* @param[in] cvv Vector of variables from CLIgen command-line
|
||||||
* @param[in] argv Vector oif user-supplied keywords
|
* @param[in] argv Vector of user-supplied keywords
|
||||||
* Format of argv:
|
* Format of argv:
|
||||||
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
||||||
* <dbname> "running"|"candidate"|"startup"
|
* <dbname> "running"|"candidate"|"startup"
|
||||||
|
|
@ -328,7 +338,7 @@ cli_auto_show(clicon_handle h,
|
||||||
cg_var *boolcv = NULL;
|
cg_var *boolcv = NULL;
|
||||||
|
|
||||||
if (cvec_len(argv) != 5 && cvec_len(argv) != 6){
|
if (cvec_len(argv) != 5 && cvec_len(argv) != 6){
|
||||||
clicon_err(OE_PLUGIN, 0, "Usage: <treename> <database> <format> <pretty> <state> [<prefix>].");
|
clicon_err(OE_PLUGIN, EINVAL, "Usage: <treename> <database> <format> <pretty> <state> [<prefix>].");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* First argv argument: treename */
|
/* First argv argument: treename */
|
||||||
|
|
@ -557,3 +567,123 @@ cli_auto_del(clicon_handle h,
|
||||||
cvec_free(cvv2);
|
cvec_free(cvv2);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct findpt_arg{
|
||||||
|
char *fa_str; /* search string */
|
||||||
|
cg_obj *fa_co; /* result */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! Iterate through parse-tree to find first argument set by cli_generate code
|
||||||
|
* @see cg_applyfn_t
|
||||||
|
* @param[in] co CLIgen parse-tree object
|
||||||
|
* @param[in] arg Argument, cast to application-specific info
|
||||||
|
* @retval -1 Error: break and return
|
||||||
|
* @retval 0 OK and continue
|
||||||
|
* @retval 1 OK and return (abort iteration)
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cli_auto_findpt(cg_obj *co,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
struct findpt_arg *fa = (struct findpt_arg *)arg;
|
||||||
|
cvec *cvv;
|
||||||
|
|
||||||
|
if (co->co_callbacks && (cvv = co->co_callbacks->cc_cvec))
|
||||||
|
if (strcmp(fa->fa_str, cv_string_get(cvec_i(cvv, 0))) == 0){
|
||||||
|
fa->fa_co = co;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Delete datastore xml
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] cvv Vector of cli string and instantiated variables
|
||||||
|
* @param[in] argv Vector of args to function in command.
|
||||||
|
* Format of argv:
|
||||||
|
* <api_path_fmt> Generated API PATH FORMAT (print-like for variables)
|
||||||
|
* <vars>* List of static variables that can be used as values for api_path_fmt
|
||||||
|
* In this example all static variables are added and dynamic variables are appended
|
||||||
|
* But this can be done differently
|
||||||
|
* Example:
|
||||||
|
* api_path_fmt=/a/b=%s,%s/c
|
||||||
|
* cvv: "cmd 42", 42
|
||||||
|
* argv: 99
|
||||||
|
* api_path: /a/b=42,99/c
|
||||||
|
* @see cli_auto_edit
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cli_auto_sub_enter(clicon_handle h,
|
||||||
|
cvec *cvv,
|
||||||
|
cvec *argv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *api_path_fmt; /* Contains wildcards as %.. */
|
||||||
|
char *api_path = NULL;
|
||||||
|
char *treename;
|
||||||
|
cvec *cvv1 = NULL;
|
||||||
|
int i;
|
||||||
|
cg_var *cv = NULL;
|
||||||
|
pt_head *ph;
|
||||||
|
struct findpt_arg fa = {0,};
|
||||||
|
|
||||||
|
if (cvec_len(argv) < 2){
|
||||||
|
clicon_err(OE_PLUGIN, EINVAL, "Usage: %s(<tree> <api_path_fmt> (,vars)*)", __FUNCTION__);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* First argv argument: treename */
|
||||||
|
cv = cvec_i(argv, 0);
|
||||||
|
treename = cv_string_get(cv);
|
||||||
|
/* Second argv argument: API_path format */
|
||||||
|
cv = cvec_i(argv, 1);
|
||||||
|
api_path_fmt = cv_string_get(cv);
|
||||||
|
|
||||||
|
/* if api_path_fmt contains print like % statements,
|
||||||
|
* values must be assigned, either dynaically from cvv (cli command line) or statically
|
||||||
|
* in code here.
|
||||||
|
* This is done by constructing a cvv1 here which suits your needs
|
||||||
|
* In this example all variables from cvv are appended with all given static variables in
|
||||||
|
* argv, but this can be done differently
|
||||||
|
*/
|
||||||
|
/* Create a cvv with variables to add to api-path */
|
||||||
|
if ((cvv1 = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Append static variables (skip first treename) */
|
||||||
|
for (i=1; i<cvec_len(argv); i++){
|
||||||
|
if (cvec_append_var(cvv1, cvec_i(argv, i)) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Append dynamic variables from the command line (skip first contains whole command line) */
|
||||||
|
for (i=1; i<cvec_len(cvv); i++){
|
||||||
|
if (cvec_append_var(cvv1, cvec_i(cvv, i)) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (api_path_fmt2api_path(api_path_fmt, cvv1, &api_path) < 0)
|
||||||
|
goto done;
|
||||||
|
/* Set the mode as a static variable to this command */
|
||||||
|
if (clicon_data_set(h, "cli-edit-mode", api_path) < 0)
|
||||||
|
goto done;
|
||||||
|
/* Assign the variables */
|
||||||
|
if (cvec_append(clicon_data_cvec_get(h, "cli-edit-cvv"), cvv1) == NULL)
|
||||||
|
goto done;
|
||||||
|
/* Find current cligen tree */
|
||||||
|
if ((ph = cligen_ph_find(cli_cligen(h), treename)) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "No such parsetree header: %s", treename);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Find the point in the generated clispec tree where workpoint should be set */
|
||||||
|
fa.fa_str = api_path_fmt;
|
||||||
|
if (pt_apply(cligen_ph_parsetree_get(ph), cli_auto_findpt, &fa) < 0)
|
||||||
|
goto done;
|
||||||
|
if (fa.fa_co)
|
||||||
|
cligen_ph_workpoint_set(ph, fa.fa_co);
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (api_path)
|
||||||
|
free(api_path);
|
||||||
|
if (cvv1)
|
||||||
|
cvec_free(cvv1);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ cli_dbxml(clicon_handle h,
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires one element to be xml key format string");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires one element to be xml key format string");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
|
@ -438,7 +438,7 @@ cli_debug_cli(clicon_handle h,
|
||||||
|
|
||||||
if ((cv = cvec_find(vars, "level")) == NULL){
|
if ((cv = cvec_find(vars, "level")) == NULL){
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires either label var or single arg: 0|1");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires either label var or single arg: 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
|
|
@ -469,7 +469,7 @@ cli_debug_backend(clicon_handle h,
|
||||||
|
|
||||||
if ((cv = cvec_find(vars, "level")) == NULL){
|
if ((cv = cvec_find(vars, "level")) == NULL){
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires either label var or single arg: 0|1");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires either label var or single arg: 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
|
|
@ -499,7 +499,7 @@ cli_debug_restconf(clicon_handle h,
|
||||||
|
|
||||||
if ((cv = cvec_find(vars, "level")) == NULL){
|
if ((cv = cvec_find(vars, "level")) == NULL){
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires either label var or single arg: 0|1");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires either label var or single arg: 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
|
|
@ -524,7 +524,7 @@ cli_set_mode(clicon_handle h,
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires one element to be cli mode");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires one element to be cli mode");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
str = cv_string_get(cvec_i(argv, 0));
|
str = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -722,7 +722,7 @@ compare_dbs(clicon_handle h,
|
||||||
int astext;
|
int astext;
|
||||||
|
|
||||||
if (cvec_len(argv) > 1){
|
if (cvec_len(argv) > 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires 0 or 1 element. If given: astext flag 0|1");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires 0 or 1 element. If given: astext flag 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (cvec_len(argv))
|
if (cvec_len(argv))
|
||||||
|
|
@ -785,9 +785,9 @@ load_config_file(clicon_handle h,
|
||||||
|
|
||||||
if (cvec_len(argv) != 2){
|
if (cvec_len(argv) != 2){
|
||||||
if (cvec_len(argv)==1)
|
if (cvec_len(argv)==1)
|
||||||
clicon_err(OE_PLUGIN, 0, "Got single argument:\"%s\". Expected \"<varname>,<op>\"", cv_string_get(cvec_i(argv,0)));
|
clicon_err(OE_PLUGIN, EINVAL, "Got single argument:\"%s\". Expected \"<varname>,<op>\"", cv_string_get(cvec_i(argv,0)));
|
||||||
else
|
else
|
||||||
clicon_err(OE_PLUGIN, 0, "Got %d arguments. Expected: <varname>,<op>", cvec_len(argv));
|
clicon_err(OE_PLUGIN, EINVAL, "Got %d arguments. Expected: <varname>,<op>", cvec_len(argv));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
varstr = cv_string_get(cvec_i(argv, 0));
|
varstr = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -874,10 +874,10 @@ save_config_file(clicon_handle h,
|
||||||
|
|
||||||
if (cvec_len(argv) != 2){
|
if (cvec_len(argv) != 2){
|
||||||
if (cvec_len(argv)==1)
|
if (cvec_len(argv)==1)
|
||||||
clicon_err(OE_PLUGIN, 0, "Got single argument:\"%s\". Expected \"<dbname>,<varname>\"",
|
clicon_err(OE_PLUGIN, EINVAL, "Got single argument:\"%s\". Expected \"<dbname>,<varname>\"",
|
||||||
cv_string_get(cvec_i(argv,0)));
|
cv_string_get(cvec_i(argv,0)));
|
||||||
else
|
else
|
||||||
clicon_err(OE_PLUGIN, 0, " Got %d arguments. Expected: <dbname>,<varname>",
|
clicon_err(OE_PLUGIN, EINVAL, " Got %d arguments. Expected: <dbname>,<varname>",
|
||||||
cvec_len(argv));
|
cvec_len(argv));
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -938,7 +938,7 @@ delete_all(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires one element: dbname");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires one element: dbname");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
dbstr = cv_string_get(cvec_i(argv, 0));
|
dbstr = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -1070,7 +1070,7 @@ cli_notify(clicon_handle h,
|
||||||
enum format_enum format = FORMAT_TEXT;
|
enum format_enum format = FORMAT_TEXT;
|
||||||
|
|
||||||
if (cvec_len(argv) != 2 && cvec_len(argv) != 3){
|
if (cvec_len(argv) != 2 && cvec_len(argv) != 3){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires arguments: <logstream> <status> [<format>]");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires arguments: <logstream> <status> [<format>]");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
stream = cv_string_get(cvec_i(argv, 0));
|
stream = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -1112,7 +1112,7 @@ cli_lock(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires arguments: <db>");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires arguments: <db>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
db = cv_string_get(cvec_i(argv, 0));
|
db = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -1142,7 +1142,7 @@ cli_unlock(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires arguments: <db>");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires arguments: <db>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
db = cv_string_get(cvec_i(argv, 0));
|
db = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -1203,7 +1203,7 @@ cli_copy_config(clicon_handle h,
|
||||||
cvec *nsc = NULL;
|
cvec *nsc = NULL;
|
||||||
|
|
||||||
if (cvec_len(argv) != 6){
|
if (cvec_len(argv) != 6){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* First argv argument: Database */
|
/* First argv argument: Database */
|
||||||
|
|
|
||||||
|
|
@ -105,8 +105,6 @@ You can see which CLISPEC it generates via clixon_cli -D 2:
|
||||||
* @param[in] cvtype Type of the cligen variable
|
* @param[in] cvtype Type of the cligen variable
|
||||||
* @param[in] options
|
* @param[in] options
|
||||||
* @param[in] fraction_digits
|
* @param[in] fraction_digits
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb The string where the result format string is inserted.
|
* @param[out] cb The string where the result format string is inserted.
|
||||||
|
|
||||||
* @see expand_dbvar This is where the expand string is used
|
* @see expand_dbvar This is where the expand string is used
|
||||||
|
|
@ -118,14 +116,12 @@ cli_expand_var_generate(clicon_handle h,
|
||||||
enum cv_type cvtype,
|
enum cv_type cvtype,
|
||||||
int options,
|
int options,
|
||||||
uint8_t fraction_digits,
|
uint8_t fraction_digits,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *api_path_fmt = NULL;
|
char *api_path_fmt = NULL;
|
||||||
|
|
||||||
if (yang2api_path_fmt(ys, 1, yp0, yp0_path, &api_path_fmt) < 0)
|
if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "|<%s:%s", yang_argument_get(ys),
|
cprintf(cb, "|<%s:%s", yang_argument_get(ys),
|
||||||
cv_type2str(cvtype));
|
cv_type2str(cvtype));
|
||||||
|
|
@ -144,8 +140,6 @@ cli_expand_var_generate(clicon_handle h,
|
||||||
/*! Create callback with api_path format string as argument
|
/*! Create callback with api_path format string as argument
|
||||||
* @param[in] h clicon handle
|
* @param[in] h clicon handle
|
||||||
* @param[in] ys yang_stmt of the node at hand
|
* @param[in] ys yang_stmt of the node at hand
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb The string where the result format string is inserted.
|
* @param[out] cb The string where the result format string is inserted.
|
||||||
* @see cli_dbxml This is where the xmlkeyfmt string is used
|
* @see cli_dbxml This is where the xmlkeyfmt string is used
|
||||||
* @see pt_callback_reference in CLIgen where the actual callback overwrites the template
|
* @see pt_callback_reference in CLIgen where the actual callback overwrites the template
|
||||||
|
|
@ -153,14 +147,12 @@ cli_expand_var_generate(clicon_handle h,
|
||||||
static int
|
static int
|
||||||
cli_callback_generate(clicon_handle h,
|
cli_callback_generate(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *api_path_fmt = NULL;
|
char *api_path_fmt = NULL;
|
||||||
|
|
||||||
if (yang2api_path_fmt(ys, 0, yp0, yp0_path, &api_path_fmt) < 0)
|
if (yang2api_path_fmt(ys, 0, &api_path_fmt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, ",%s(\"%s\")", GENERATE_CALLBACK,
|
cprintf(cb, ",%s(\"%s\")", GENERATE_CALLBACK,
|
||||||
api_path_fmt);
|
api_path_fmt);
|
||||||
|
|
@ -363,7 +355,7 @@ yang2cli_var_pattern(clicon_handle h,
|
||||||
/* Forward */
|
/* Forward */
|
||||||
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys, enum genmodel_type gt,
|
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys, enum genmodel_type gt,
|
||||||
int level, int state, int show_tree,
|
int level, int state, int show_tree,
|
||||||
yang_stmt *yp0, char *yp0_path, cbuf *cb);
|
cbuf *cb);
|
||||||
|
|
||||||
static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, char *origtype,
|
static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, char *origtype,
|
||||||
yang_stmt *ytype, char *helptext, cbuf *cb);
|
yang_stmt *ytype, char *helptext, cbuf *cb);
|
||||||
|
|
@ -558,8 +550,6 @@ yang2cli_var_union(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] ys Yang statement
|
* @param[in] ys Yang statement
|
||||||
* @param[in] helptext CLI help text
|
* @param[in] helptext CLI help text
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
@ -573,8 +563,6 @@ static int
|
||||||
yang2cli_var(clicon_handle h,
|
yang2cli_var(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
char *helptext,
|
char *helptext,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -613,7 +601,6 @@ yang2cli_var(clicon_handle h,
|
||||||
if (clicon_cli_genmodel_completion(h)){
|
if (clicon_cli_genmodel_completion(h)){
|
||||||
if (cli_expand_var_generate(h, ys, cvtype,
|
if (cli_expand_var_generate(h, ys, cvtype,
|
||||||
options, fraction_digits,
|
options, fraction_digits,
|
||||||
yp0, yp0_path,
|
|
||||||
cb) < 0)
|
cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
yang2cli_helptext(cb, helptext);
|
yang2cli_helptext(cb, helptext);
|
||||||
|
|
@ -637,7 +624,6 @@ yang2cli_var(clicon_handle h,
|
||||||
if (completionp){
|
if (completionp){
|
||||||
if (cli_expand_var_generate(h, ys, cvtype,
|
if (cli_expand_var_generate(h, ys, cvtype,
|
||||||
options, fraction_digits,
|
options, fraction_digits,
|
||||||
yp0, yp0_path,
|
|
||||||
cb) < 0)
|
cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
yang2cli_helptext(cb, helptext);
|
yang2cli_helptext(cb, helptext);
|
||||||
|
|
@ -661,8 +647,6 @@ yang2cli_var(clicon_handle h,
|
||||||
* @param[in] callback If set, include a "; cli_set()" callback, otherwise not
|
* @param[in] callback If set, include a "; cli_set()" callback, otherwise not
|
||||||
* @param[in] show_tree Is tree for show cli command
|
* @param[in] show_tree Is tree for show cli command
|
||||||
* @param[in] key_leaf Is leaf in a key in a list module
|
* @param[in] key_leaf Is leaf in a key in a list module
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -673,8 +657,6 @@ yang2cli_leaf(clicon_handle h,
|
||||||
int callback,
|
int callback,
|
||||||
int show_tree,
|
int show_tree,
|
||||||
int key_leaf,
|
int key_leaf,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
yang_stmt *yd; /* description */
|
yang_stmt *yd; /* description */
|
||||||
|
|
@ -697,18 +679,18 @@ yang2cli_leaf(clicon_handle h,
|
||||||
yang2cli_helptext(cb, helptext);
|
yang2cli_helptext(cb, helptext);
|
||||||
cprintf(cb, " ");
|
cprintf(cb, " ");
|
||||||
if ((show_tree == 0) || (key_leaf == 1)) {
|
if ((show_tree == 0) || (key_leaf == 1)) {
|
||||||
if (yang2cli_var(h, ys, helptext, yp0, yp0_path, cb) < 0)
|
if (yang2cli_var(h, ys, helptext, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((show_tree == 0) || (key_leaf == 1)) {
|
if ((show_tree == 0) || (key_leaf == 1)) {
|
||||||
if (yang2cli_var(h, ys, helptext, yp0, yp0_path, cb) < 0)
|
if (yang2cli_var(h, ys, helptext, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback){
|
if (callback){
|
||||||
if (cli_callback_generate(h, ys, yp0, yp0_path, cb) < 0)
|
if (cli_callback_generate(h, ys, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, ";\n");
|
cprintf(cb, ";\n");
|
||||||
}
|
}
|
||||||
|
|
@ -727,8 +709,6 @@ yang2cli_leaf(clicon_handle h,
|
||||||
* @param[in] level Indentation level
|
* @param[in] level Indentation level
|
||||||
* @param[in] state Include syntax for state not only config
|
* @param[in] state Include syntax for state not only config
|
||||||
* @param[in] show_tree Is tree for show cli command
|
* @param[in] show_tree Is tree for show cli command
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -738,8 +718,6 @@ yang2cli_container(clicon_handle h,
|
||||||
int level,
|
int level,
|
||||||
int state,
|
int state,
|
||||||
int show_tree,
|
int show_tree,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
yang_stmt *yc;
|
yang_stmt *yc;
|
||||||
|
|
@ -764,14 +742,14 @@ yang2cli_container(clicon_handle h,
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
yang2cli_helptext(cb, helptext);
|
yang2cli_helptext(cb, helptext);
|
||||||
}
|
}
|
||||||
if (cli_callback_generate(h, ys, yp0, yp0_path, cb) < 0)
|
if (cli_callback_generate(h, ys, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, ";{\n");
|
cprintf(cb, ";{\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
yc = NULL;
|
yc = NULL;
|
||||||
while ((yc = yn_each(ys, yc)) != NULL)
|
while ((yc = yn_each(ys, yc)) != NULL)
|
||||||
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, yp0, yp0_path, cb) < 0)
|
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (hide == 0)
|
if (hide == 0)
|
||||||
cprintf(cb, "%*s}\n", level*3, "");
|
cprintf(cb, "%*s}\n", level*3, "");
|
||||||
|
|
@ -789,8 +767,6 @@ yang2cli_container(clicon_handle h,
|
||||||
* @param[in] level Indentation level
|
* @param[in] level Indentation level
|
||||||
* @param[in] state Include syntax for state not only config
|
* @param[in] state Include syntax for state not only config
|
||||||
* @param[in] show_tree Is tree for show cli command
|
* @param[in] show_tree Is tree for show cli command
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -800,8 +776,6 @@ yang2cli_list(clicon_handle h,
|
||||||
int level,
|
int level,
|
||||||
int state,
|
int state,
|
||||||
int show_tree,
|
int show_tree,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
yang_stmt *yc;
|
yang_stmt *yc;
|
||||||
|
|
@ -842,7 +816,7 @@ yang2cli_list(clicon_handle h,
|
||||||
list_has_callback = cvec_next(cvk, cvi)?0:1;
|
list_has_callback = cvec_next(cvk, cvi)?0:1;
|
||||||
if (show_tree == 1) {
|
if (show_tree == 1) {
|
||||||
if (list_has_callback) {
|
if (list_has_callback) {
|
||||||
if (cli_callback_generate(h, ys, yp0, yp0_path, cb) < 0)
|
if (cli_callback_generate(h, ys, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, ";\n");
|
cprintf(cb, ";\n");
|
||||||
cprintf(cb, "{\n");
|
cprintf(cb, "{\n");
|
||||||
|
|
@ -852,7 +826,6 @@ yang2cli_list(clicon_handle h,
|
||||||
if (yang2cli_leaf(h, yleaf,
|
if (yang2cli_leaf(h, yleaf,
|
||||||
(gt==GT_VARS||gt==GT_HIDE)?GT_NONE:gt, level+1,
|
(gt==GT_VARS||gt==GT_HIDE)?GT_NONE:gt, level+1,
|
||||||
list_has_callback, show_tree, 1,
|
list_has_callback, show_tree, 1,
|
||||||
yp0, yp0_path,
|
|
||||||
cb) < 0)
|
cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -871,7 +844,7 @@ yang2cli_list(clicon_handle h,
|
||||||
}
|
}
|
||||||
if (cvi != NULL)
|
if (cvi != NULL)
|
||||||
continue;
|
continue;
|
||||||
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, yp0, yp0_path, cb) < 0)
|
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cb, "%*s}\n", level*3, "");
|
cprintf(cb, "%*s}\n", level*3, "");
|
||||||
|
|
@ -893,8 +866,6 @@ yang2cli_list(clicon_handle h,
|
||||||
* @param[in] level Indentation level
|
* @param[in] level Indentation level
|
||||||
* @param[in] state Include syntax for state not only config
|
* @param[in] state Include syntax for state not only config
|
||||||
* @param[in] show_tree Is tree for show cli command
|
* @param[in] show_tree Is tree for show cli command
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
@example
|
@example
|
||||||
choice interface-type {
|
choice interface-type {
|
||||||
|
|
@ -912,8 +883,6 @@ yang2cli_choice(clicon_handle h,
|
||||||
int level,
|
int level,
|
||||||
int state,
|
int state,
|
||||||
int show_tree,
|
int show_tree,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -923,7 +892,7 @@ yang2cli_choice(clicon_handle h,
|
||||||
while ((yc = yn_each(ys, yc)) != NULL) {
|
while ((yc = yn_each(ys, yc)) != NULL) {
|
||||||
switch (yang_keyword_get(yc)){
|
switch (yang_keyword_get(yc)){
|
||||||
case Y_CASE:
|
case Y_CASE:
|
||||||
if (yang2cli_stmt(h, yc, gt, level+2, state, show_tree, yp0, yp0_path, cb) < 0)
|
if (yang2cli_stmt(h, yc, gt, level+2, state, show_tree, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_CONTAINER:
|
case Y_CONTAINER:
|
||||||
|
|
@ -931,7 +900,7 @@ yang2cli_choice(clicon_handle h,
|
||||||
case Y_LEAF_LIST:
|
case Y_LEAF_LIST:
|
||||||
case Y_LIST:
|
case Y_LIST:
|
||||||
default:
|
default:
|
||||||
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, yp0, yp0_path, cb) < 0)
|
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -948,8 +917,6 @@ yang2cli_choice(clicon_handle h,
|
||||||
* @param[in] level Indentation level
|
* @param[in] level Indentation level
|
||||||
* @param[in] state Include syntax for state not only config
|
* @param[in] state Include syntax for state not only config
|
||||||
* @param[in] show_tree Is tree for show cli command
|
* @param[in] show_tree Is tree for show cli command
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -959,8 +926,6 @@ yang2cli_stmt(clicon_handle h,
|
||||||
int level,
|
int level,
|
||||||
int state,
|
int state,
|
||||||
int show_tree,
|
int show_tree,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
yang_stmt *yc;
|
yang_stmt *yc;
|
||||||
|
|
@ -969,24 +934,20 @@ yang2cli_stmt(clicon_handle h,
|
||||||
if (state || yang_config(ys)){
|
if (state || yang_config(ys)){
|
||||||
switch (yang_keyword_get(ys)){
|
switch (yang_keyword_get(ys)){
|
||||||
case Y_CONTAINER:
|
case Y_CONTAINER:
|
||||||
if (yang2cli_container(h, ys, gt, level, state, show_tree,
|
if (yang2cli_container(h, ys, gt, level, state, show_tree, cb) < 0)
|
||||||
yp0, yp0_path, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_LIST:
|
case Y_LIST:
|
||||||
if (yang2cli_list(h, ys, gt, level, state, show_tree,
|
if (yang2cli_list(h, ys, gt, level, state, show_tree, cb) < 0)
|
||||||
yp0, yp0_path, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_CHOICE:
|
case Y_CHOICE:
|
||||||
if (yang2cli_choice(h, ys, gt, level, state, show_tree,
|
if (yang2cli_choice(h, ys, gt, level, state, show_tree, cb) < 0)
|
||||||
yp0, yp0_path, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_LEAF_LIST:
|
case Y_LEAF_LIST:
|
||||||
case Y_LEAF:
|
case Y_LEAF:
|
||||||
if (yang2cli_leaf(h, ys, gt, level, 1, show_tree, 0,
|
if (yang2cli_leaf(h, ys, gt, level, 1, show_tree, 0, cb) < 0)
|
||||||
yp0, yp0_path, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_CASE:
|
case Y_CASE:
|
||||||
|
|
@ -994,8 +955,7 @@ yang2cli_stmt(clicon_handle h,
|
||||||
case Y_MODULE:
|
case Y_MODULE:
|
||||||
yc = NULL;
|
yc = NULL;
|
||||||
while ((yc = yn_each(ys, yc)) != NULL)
|
while ((yc = yn_each(ys, yc)) != NULL)
|
||||||
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree,
|
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, cb) < 0)
|
||||||
yp0, yp0_path, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
default: /* skip */
|
default: /* skip */
|
||||||
|
|
@ -1013,8 +973,6 @@ yang2cli_stmt(clicon_handle h,
|
||||||
* @param[in] printgen Log generated CLIgen syntax
|
* @param[in] printgen Log generated CLIgen syntax
|
||||||
* @param[in] state Set to include state syntax
|
* @param[in] state Set to include state syntax
|
||||||
* @param[in] show_tree Is tree for show cli command
|
* @param[in] show_tree Is tree for show cli command
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] pt CLIgen parse-tree (must be created on input)
|
* @param[out] pt CLIgen parse-tree (must be created on input)
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -1025,8 +983,6 @@ yang2cli(clicon_handle h,
|
||||||
int printgen,
|
int printgen,
|
||||||
int state,
|
int state,
|
||||||
int show_tree,
|
int show_tree,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
parse_tree *pt)
|
parse_tree *pt)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -1047,8 +1003,7 @@ yang2cli(clicon_handle h,
|
||||||
/* Traverse YANG, loop through all modules and generate CLI */
|
/* Traverse YANG, loop through all modules and generate CLI */
|
||||||
yc = NULL;
|
yc = NULL;
|
||||||
while ((yc = yn_each(yn, yc)) != NULL)
|
while ((yc = yn_each(yn, yc)) != NULL)
|
||||||
if (yang2cli_stmt(h, yc, gt, 0, state, show_tree,
|
if (yang2cli_stmt(h, yc, gt, 0, state, show_tree, cb) < 0)
|
||||||
yp0, yp0_path, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (printgen)
|
if (printgen)
|
||||||
clicon_log(LOG_NOTICE, "%s: Generated CLI spec:\n%s", __FUNCTION__, cbuf_get(cb));
|
clicon_log(LOG_NOTICE, "%s: Generated CLI spec:\n%s", __FUNCTION__, cbuf_get(cb));
|
||||||
|
|
@ -1077,50 +1032,3 @@ yang2cli(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Generate CLI code for Yang specification
|
|
||||||
* @param[in] h Clixon handle
|
|
||||||
* @param[in] api_path API-path of sub-xml/yang
|
|
||||||
* @param[in] name Name of tree: use @<name> in clispec
|
|
||||||
* @param[in] printgen Log generated CLIgen syntax
|
|
||||||
* @param[in] state Also include state syntax
|
|
||||||
* @retval -1 Error, with clicon_err called
|
|
||||||
* @retval 0 OK , with result in yres
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
yang2cli_sub(clicon_handle h,
|
|
||||||
char *api_path,
|
|
||||||
char *name,
|
|
||||||
int printgen,
|
|
||||||
int state)
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
yang_stmt *yspec;
|
|
||||||
yang_stmt *yn = NULL;
|
|
||||||
pt_head *ph;
|
|
||||||
parse_tree *pt = NULL; /* cli parse tree */
|
|
||||||
|
|
||||||
/* Get yspec */
|
|
||||||
yspec = clicon_dbspec_yang(h);
|
|
||||||
if (api_path2xml(api_path, yspec, NULL, YC_DATANODE, 1, NULL, &yn, NULL) < 0)
|
|
||||||
goto done;
|
|
||||||
if (yn == NULL)
|
|
||||||
goto ok; /* not found */
|
|
||||||
/* Create empty parse-tree */
|
|
||||||
if ((pt = pt_new()) == NULL){
|
|
||||||
clicon_err(OE_UNIX, errno, "pt_new");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/* Generate tree from yangnode yn */
|
|
||||||
if (yang2cli(h, yn, printgen, state, 0, yn, api_path, pt) < 0)
|
|
||||||
goto done;
|
|
||||||
/* Add a new parse-tree header */
|
|
||||||
if ((ph = cligen_ph_add(cli_cligen(h), name)) == NULL)
|
|
||||||
goto done;
|
|
||||||
/* Add generated parse-tree to header */
|
|
||||||
if (cligen_ph_parsetree_set(ph, pt) < 0)
|
|
||||||
goto done;
|
|
||||||
ok:
|
|
||||||
retval = 0;
|
|
||||||
done:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,6 @@
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int yang2cli(clicon_handle h, yang_stmt *yspec,
|
int yang2cli(clicon_handle h, yang_stmt *yspec,
|
||||||
int printgen, int state, int show_tree,
|
int printgen, int state, int show_tree, parse_tree *ptnew);
|
||||||
yang_stmt *yp0, char *yp0_path, parse_tree *ptnew);
|
|
||||||
int yang2cli_sub(clicon_handle h, char *api_path, char *name, int printgen, int state);
|
|
||||||
|
|
||||||
#endif /* _CLI_GENERATE_H_ */
|
#endif /* _CLI_GENERATE_H_ */
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ autocli_tree(clicon_handle h,
|
||||||
}
|
}
|
||||||
yspec = clicon_dbspec_yang(h);
|
yspec = clicon_dbspec_yang(h);
|
||||||
/* Generate tree (this is where the action is) */
|
/* Generate tree (this is where the action is) */
|
||||||
if (yang2cli(h, yspec, printgen, state, show_tree, NULL, NULL, pt) < 0)
|
if (yang2cli(h, yspec, printgen, state, show_tree, pt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Append cligen tree and name it */
|
/* Append cligen tree and name it */
|
||||||
if ((ph = cligen_ph_add(cli_cligen(h), name)) == NULL)
|
if ((ph = cligen_ph_add(cli_cligen(h), name)) == NULL)
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ expand_dbvar(void *h,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (argv == NULL || cvec_len(argv) != 2){
|
if (argv == NULL || cvec_len(argv) != 2){
|
||||||
clicon_err(OE_PLUGIN, 0, "requires arguments: <db> <xmlkeyfmt>");
|
clicon_err(OE_PLUGIN, EINVAL, "requires arguments: <db> <xmlkeyfmt>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
|
@ -451,7 +451,7 @@ cli_show_config1(clicon_handle h,
|
||||||
char *prefix = NULL;
|
char *prefix = NULL;
|
||||||
|
|
||||||
if (cvec_len(argv) < 3 || cvec_len(argv) > 5){
|
if (cvec_len(argv) < 3 || cvec_len(argv) > 5){
|
||||||
clicon_err(OE_PLUGIN, 0, "Got %d arguments. Expected: <dbname>,<format>,<xpath>[,<namespace>, [<prefix>]]", cvec_len(argv));
|
clicon_err(OE_PLUGIN, EINVAL, "Got %d arguments. Expected: <dbname>,<format>,<xpath>[,<namespace>, [<prefix>]]", cvec_len(argv));
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -618,7 +618,7 @@ show_conf_xpath(clicon_handle h,
|
||||||
cvec *nsc = NULL;
|
cvec *nsc = NULL;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "Requires one element to be <dbname>");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires one element to be <dbname>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
str = cv_string_get(cvec_i(argv, 0));
|
str = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -713,7 +713,7 @@ cli_show_auto1(clicon_handle h,
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (cvec_len(argv) < 3 || cvec_len(argv) > 4){
|
if (cvec_len(argv) < 3 || cvec_len(argv) > 4){
|
||||||
clicon_err(OE_PLUGIN, 0, "Usage: <api-path-fmt>* <database> <format> <prefix>. (*) generated.");
|
clicon_err(OE_PLUGIN, EINVAL, "Usage: <api-path-fmt>* <database> <format> <prefix>. (*) generated.");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* First argv argument: API_path format */
|
/* First argv argument: API_path format */
|
||||||
|
|
|
||||||
|
|
@ -141,5 +141,6 @@ int cli_auto_set(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_auto_merge(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_auto_merge(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_auto_create(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_auto_create(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_auto_del(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_auto_del(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
|
int cli_auto_sub_enter(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
|
|
||||||
#endif /* _CLIXON_CLI_API_H_ */
|
#endif /* _CLIXON_CLI_API_H_ */
|
||||||
|
|
|
||||||
|
|
@ -132,24 +132,10 @@ example_client_rpc(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plugin start
|
|
||||||
* Example on creating a generated tree from a sub-part of a yang spec.
|
|
||||||
* which can then be used in a clispec as: @datamodelexample.
|
|
||||||
* @see test_cli_gen_sub.sh
|
|
||||||
* @note still experimental
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
example_start(clicon_handle h)
|
|
||||||
{
|
|
||||||
if (yang2cli_sub(h, "/example2:table/parameter=abc", "datamodelexample", 1, 0) < 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static clixon_plugin_api api = {
|
static clixon_plugin_api api = {
|
||||||
"example", /* name */
|
"example", /* name */
|
||||||
clixon_plugin_init, /* init */
|
clixon_plugin_init, /* init */
|
||||||
example_start, /* start */
|
NULL, /* start */
|
||||||
NULL, /* exit */
|
NULL, /* exit */
|
||||||
.ca_prompt=NULL, /* cli_prompthook_t */
|
.ca_prompt=NULL, /* cli_prompthook_t */
|
||||||
.ca_suspend=NULL, /* cligen_susp_cb_t */
|
.ca_suspend=NULL, /* cligen_susp_cb_t */
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,9 @@ CLICON_PROMPT="%U@%H %W> ";
|
||||||
CLICON_PLUGIN="example_cli";
|
CLICON_PLUGIN="example_cli";
|
||||||
|
|
||||||
# Autocli syntax tree operations
|
# Autocli syntax tree operations
|
||||||
edit @datamodel, cli_auto_edit("datamodel", "candidate");
|
edit @datamodel, cli_auto_edit("datamodel");
|
||||||
up, cli_auto_up("datamodel", "candidate");
|
up, cli_auto_up("datamodel");
|
||||||
top, cli_auto_top("datamodel", "candidate");
|
top, cli_auto_top("datamodel");
|
||||||
set @datamodel, cli_auto_set();
|
set @datamodel, cli_auto_set();
|
||||||
merge @datamodel, cli_auto_merge();
|
merge @datamodel, cli_auto_merge();
|
||||||
create @datamodel, cli_auto_create();
|
create @datamodel, cli_auto_create();
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,8 @@ typedef struct {
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int xml_yang_root(cxobj *x, cxobj **xr);
|
int xml_yang_root(cxobj *x, cxobj **xr);
|
||||||
int yang2api_path_fmt(yang_stmt *ys, int inclkey, yang_stmt *yp0, char *yp0_path,
|
int yang2api_path_fmt(yang_stmt *ys, int inclkey, char **api_path_fmt);
|
||||||
char **api_path_fmt);
|
int api_path_fmt2api_path(const char *api_path_fmt, cvec *cvv, char **api_path);
|
||||||
int api_path_fmt2api_path(char *api_path_fmt, cvec *cvv, char **api_path);
|
|
||||||
int api_path_fmt2xpath(char *api_path_fmt, cvec *cvv, char **xpath);
|
int api_path_fmt2xpath(char *api_path_fmt, cvec *cvv, char **xpath);
|
||||||
int api_path2xpath(char *api_path, yang_stmt *yspec, char **xpath, cvec **nsc, cxobj **xerr);
|
int api_path2xpath(char *api_path, yang_stmt *yspec, char **xpath, cvec **nsc, cxobj **xerr);
|
||||||
int api_path2xml(char *api_path, yang_stmt *yspec, cxobj *xtop,
|
int api_path2xml(char *api_path, yang_stmt *yspec, cxobj *xtop,
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ clicon_data_del(clicon_handle h,
|
||||||
return clicon_hash_del(cdat, (char*)name);
|
return clicon_hash_del(cdat, (char*)name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get generic cligen varaibel vector (cvv) on the form <name>=<val> where <val> is cvv
|
/*! Get generic cligen variable vector (cvv) on the form <name>=<val> where <val> is cvv
|
||||||
*
|
*
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] name Data name
|
* @param[in] name Data name
|
||||||
|
|
|
||||||
|
|
@ -287,8 +287,6 @@ xml_yang_root(cxobj *x,
|
||||||
* path: /modname:a/b/%s/d
|
* path: /modname:a/b/%s/d
|
||||||
* @param[in] ys Yang statement
|
* @param[in] ys Yang statement
|
||||||
* @param[in] inclkey If set include key leaf (eg last leaf d in ex)
|
* @param[in] inclkey If set include key leaf (eg last leaf d in ex)
|
||||||
* @param[in] yp0 Build the path of ys only to this level not root (optional)
|
|
||||||
* @param[in] yp0path Use this path if stop at yp0 (not root)
|
|
||||||
* @param[out] cb api_path_fmt,
|
* @param[out] cb api_path_fmt,
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -297,8 +295,6 @@ xml_yang_root(cxobj *x,
|
||||||
static int
|
static int
|
||||||
yang2api_path_fmt_1(yang_stmt *ys,
|
yang2api_path_fmt_1(yang_stmt *ys,
|
||||||
int inclkey,
|
int inclkey,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
yang_stmt *yp; /* parent */
|
yang_stmt *yp; /* parent */
|
||||||
|
|
@ -312,14 +308,11 @@ yang2api_path_fmt_1(yang_stmt *ys,
|
||||||
clicon_err(OE_YANG, EINVAL, "yang expected parent %s", yang_argument_get(ys));
|
clicon_err(OE_YANG, EINVAL, "yang expected parent %s", yang_argument_get(ys));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yp == yp0){ /* Skip building path to root if match, use given path */
|
if (yp != NULL && /* XXX rm */
|
||||||
cprintf(cb, "%s/", yp0_path);
|
|
||||||
}
|
|
||||||
else if (yp != NULL && /* XXX rm */
|
|
||||||
yang_keyword_get(yp) != Y_MODULE &&
|
yang_keyword_get(yp) != Y_MODULE &&
|
||||||
yang_keyword_get(yp) != Y_SUBMODULE){
|
yang_keyword_get(yp) != Y_SUBMODULE){
|
||||||
|
|
||||||
if (yang2api_path_fmt_1((yang_stmt *)yp, 1, yp0, yp0_path, cb) < 0) /* recursive call */
|
if (yang2api_path_fmt_1((yang_stmt *)yp, 1, cb) < 0) /* recursive call */
|
||||||
goto done;
|
goto done;
|
||||||
if (yang_keyword_get(yp) != Y_CHOICE && yang_keyword_get(yp) != Y_CASE){
|
if (yang_keyword_get(yp) != Y_CHOICE && yang_keyword_get(yp) != Y_CASE){
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -398,8 +391,6 @@ yang2api_path_fmt_1(yang_stmt *ys,
|
||||||
int
|
int
|
||||||
yang2api_path_fmt(yang_stmt *ys,
|
yang2api_path_fmt(yang_stmt *ys,
|
||||||
int inclkey,
|
int inclkey,
|
||||||
yang_stmt *yp0,
|
|
||||||
char *yp0_path,
|
|
||||||
char **api_path_fmt)
|
char **api_path_fmt)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -409,7 +400,7 @@ yang2api_path_fmt(yang_stmt *ys,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yang2api_path_fmt_1(ys, inclkey, yp0, yp0_path, cb) < 0)
|
if (yang2api_path_fmt_1(ys, inclkey, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((*api_path_fmt = strdup(cbuf_get(cb))) == NULL){
|
if ((*api_path_fmt = strdup(cbuf_get(cb))) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "strdup");
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
|
@ -433,6 +424,8 @@ yang2api_path_fmt(yang_stmt *ys,
|
||||||
* @param[in] api_path_fmt XML key format, eg /aaa/%s/name
|
* @param[in] api_path_fmt XML key format, eg /aaa/%s/name
|
||||||
* @param[in] cvv cligen variable vector, one for every wildchar in api_path_fmt
|
* @param[in] cvv cligen variable vector, one for every wildchar in api_path_fmt
|
||||||
* @param[out] api_path api_path, eg /aaa/17. Free after use
|
* @param[out] api_path api_path, eg /aaa/17. Free after use
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
* @note first and last elements of cvv are not used,..
|
* @note first and last elements of cvv are not used,..
|
||||||
* @see api_path_fmt2xpath
|
* @see api_path_fmt2xpath
|
||||||
* @example
|
* @example
|
||||||
|
|
@ -445,15 +438,15 @@ yang2api_path_fmt(yang_stmt *ys,
|
||||||
* api_path: /interfaces/interface=e0/name
|
* api_path: /interfaces/interface=e0/name
|
||||||
* @example
|
* @example
|
||||||
* api_path_fmt: /subif-entry=%s,%s/subid
|
* api_path_fmt: /subif-entry=%s,%s/subid
|
||||||
* cvv: foo
|
* cvv: foo, bar
|
||||||
* api_path: /subif-entry=foo/subid
|
* api_path: /subif-entry=foo,bar/subid
|
||||||
*
|
*
|
||||||
* "api-path" is "URI-encoded path expression" definition in RFC8040 3.5.3
|
* "api-path" is "URI-encoded path expression" definition in RFC8040 3.5.3
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
api_path_fmt2api_path(char *api_path_fmt,
|
api_path_fmt2api_path(const char *api_path_fmt,
|
||||||
cvec *cvv,
|
cvec *cvv,
|
||||||
char **api_path)
|
char **api_path)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char c;
|
char c;
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,9 @@ CLICON_PROMPT="%U@%H %W> ";
|
||||||
CLICON_PLUGIN="example_cli";
|
CLICON_PLUGIN="example_cli";
|
||||||
|
|
||||||
# Autocli syntax tree operations
|
# Autocli syntax tree operations
|
||||||
edit @datamodel, cli_auto_edit("datamodel", "candidate");
|
edit @datamodel, cli_auto_edit("datamodel");
|
||||||
up, cli_auto_up("datamodel", "candidate");
|
up, cli_auto_up("datamodel");
|
||||||
top, cli_auto_top("datamodel", "candidate");
|
top, cli_auto_top("datamodel");
|
||||||
set @datamodel, cli_auto_set();
|
set @datamodel, cli_auto_set();
|
||||||
merge @datamodel, cli_auto_merge();
|
merge @datamodel, cli_auto_merge();
|
||||||
create @datamodel, cli_auto_create();
|
create @datamodel, cli_auto_create();
|
||||||
|
|
@ -213,6 +213,15 @@ EOF
|
||||||
new "set value 71"
|
new "set value 71"
|
||||||
expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "/clixon-example:table>" "<parameter><name>a</name><value>42</value></parameter><parameter><name>b</name><value>71</value></parameter>"
|
expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "/clixon-example:table>" "<parameter><name>a</name><value>42</value></parameter><parameter><name>b</name><value>71</value></parameter>"
|
||||||
|
|
||||||
|
cat <<EOF > $fin
|
||||||
|
edit table parameter a
|
||||||
|
top
|
||||||
|
edit table parameter b
|
||||||
|
show config
|
||||||
|
EOF
|
||||||
|
new "edit parameter b show"
|
||||||
|
expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "/clixon-example:table/parameter=b/>" "<name>b</name><value>71</value>" --not-- "<parameter>"
|
||||||
|
|
||||||
cat <<EOF > $fin
|
cat <<EOF > $fin
|
||||||
edit table parameter b
|
edit table parameter b
|
||||||
delete value 17
|
delete value 17
|
||||||
|
|
|
||||||
126
test/test_cli_auto_sub.sh
Executable file
126
test/test_cli_auto_sub.sh
Executable file
|
|
@ -0,0 +1,126 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Tests for generating clispec from a yang subtree
|
||||||
|
|
||||||
|
# Magic line must be first in script (see README.md)
|
||||||
|
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||||
|
|
||||||
|
APPNAME=example
|
||||||
|
|
||||||
|
# include err() and new() functions and creates $dir
|
||||||
|
|
||||||
|
# Must be defined by a call: yang2cli_sub(h, ..., "datamodelexample", ...)
|
||||||
|
fin=$dir/in
|
||||||
|
cfg=$dir/conf_yang.xml
|
||||||
|
fyang=$dir/$APPNAME.yang
|
||||||
|
clidir=$dir/cli
|
||||||
|
if [ -d $clidir ]; then
|
||||||
|
rm -rf $clidir/*
|
||||||
|
else
|
||||||
|
mkdir $clidir
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use yang in example
|
||||||
|
|
||||||
|
cat <<EOF > $cfg
|
||||||
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
|
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
||||||
|
<CLICON_CLISPEC_DIR>$clidir</CLICON_CLISPEC_DIR>
|
||||||
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
<CLICON_CLI_GENMODEL>2</CLICON_CLI_GENMODEL>
|
||||||
|
<CLICON_CLI_GENMODEL_TYPE>VARS</CLICON_CLI_GENMODEL_TYPE>
|
||||||
|
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||||
|
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||||
|
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||||
|
<CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895>
|
||||||
|
</clixon-config>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF > $fyang
|
||||||
|
module $APPNAME {
|
||||||
|
namespace "urn:example:clixon";
|
||||||
|
prefix ex;
|
||||||
|
container table{
|
||||||
|
list parameter{
|
||||||
|
key name;
|
||||||
|
leaf name{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf value{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
list index{
|
||||||
|
key i;
|
||||||
|
leaf i{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF > $clidir/ex.cli
|
||||||
|
CLICON_MODE="example";
|
||||||
|
CLICON_PROMPT="%U@%H> ";
|
||||||
|
|
||||||
|
# Manual command form where a sub-mode is created from @datamodel
|
||||||
|
# It gives: cvv eg:
|
||||||
|
# 0 : cmd = parameter 123
|
||||||
|
# 1 : string = "123"
|
||||||
|
enter <string>, cli_auto_sub_enter("datamodel", "/example:table/parameter=%s/index=%s/", "x");
|
||||||
|
leave, cli_auto_top("datamodel", "candidate");
|
||||||
|
|
||||||
|
# Autocli syntax tree operations
|
||||||
|
edit @datamodel, cli_auto_edit("interface");
|
||||||
|
up, cli_auto_up("datamodel");
|
||||||
|
top, cli_auto_top("datamodel");
|
||||||
|
set @datamodel, cli_auto_set();
|
||||||
|
merge @datamodel, cli_auto_merge();
|
||||||
|
create @datamodel, cli_auto_create();
|
||||||
|
delete("Delete a configuration item") {
|
||||||
|
@datamodel, cli_auto_del();
|
||||||
|
all("Delete whole candidate configuration"), delete_all("candidate");
|
||||||
|
}
|
||||||
|
show("Show a particular state of the system"){
|
||||||
|
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
new "test params: -f $cfg"
|
||||||
|
if [ $BE -ne 0 ]; then
|
||||||
|
new "kill old backend"
|
||||||
|
sudo clixon_backend -z -f $cfg
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
err
|
||||||
|
fi
|
||||||
|
new "start backend -s init -f $cfg"
|
||||||
|
start_backend -s init -f $cfg
|
||||||
|
|
||||||
|
new "waiting"
|
||||||
|
wait_backend
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF > $fin
|
||||||
|
enter a
|
||||||
|
leave
|
||||||
|
EOF
|
||||||
|
new "enter leave"
|
||||||
|
expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 'enter a' 'leave'
|
||||||
|
|
||||||
|
# XXX much more
|
||||||
|
|
||||||
|
new "Kill backend"
|
||||||
|
# Check if premature kill
|
||||||
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
|
if [ -z "$pid" ]; then
|
||||||
|
err "backend already dead"
|
||||||
|
fi
|
||||||
|
# kill backend
|
||||||
|
stop_backend -f $cfg
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
Loading…
Add table
Add a link
Reference in a new issue