Added completion for generated cli leafrefs for both absolute and relatve paths.

This commit is contained in:
Olof hagsand 2017-07-19 09:26:56 +02:00
parent 1b6c9aacbe
commit f995f1e268
4 changed files with 52 additions and 23 deletions

View file

@ -1,6 +1,8 @@
# Clixon CHANGELOG # Clixon CHANGELOG
- Added validation for leafref forward and nackward references. - Added completion for generated cli leafrefs for both absolute and relatve paths.
- Added validation for leafref forward and backward references.
- Added new backend plugin callback: "plugin_statedata()" for retreiving state data - Added new backend plugin callback: "plugin_statedata()" for retreiving state data

View file

@ -297,7 +297,8 @@ main(int argc, char **argv)
char *dir = dirname(str); char *dir = dirname(str);
hash_del(clicon_options(h), (char*)"CLICON_YANG_MODULE_REVISION"); hash_del(clicon_options(h), (char*)"CLICON_YANG_MODULE_REVISION");
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", basename(optarg)); clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", basename(optarg));
clicon_option_str_set(h, "CLICON_YANG_DIR", strdup(dir)); clicon_option_str_set(h, "CLICON_YANG_DIR", dir);
free(str);
break; break;
} }
default: default:

View file

@ -112,12 +112,24 @@ expand_dbvar(void *h,
int j; int j;
int k; int k;
cg_var *cv; cg_var *cv;
yang_spec *yspec;
cxobj *xtop = NULL; /* xpath root */
cxobj *xbot = NULL; /* xpath, NULL if datastore */
yang_node *y = NULL; /* yang spec of xpath */
yang_stmt *ytype;
yang_stmt *ypath;
cxobj *xcur;
char *xpathcur;
if (argv == NULL || cvec_len(argv) != 2){ if (argv == NULL || cvec_len(argv) != 2){
clicon_err(OE_PLUGIN, 0, "%s: requires arguments: <db> <xmlkeyfmt>", clicon_err(OE_PLUGIN, 0, "%s: requires arguments: <db> <xmlkeyfmt>",
__FUNCTION__); __FUNCTION__);
goto done; goto done;
} }
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done;
}
if ((cv = cvec_i(argv, 0)) == NULL){ if ((cv = cvec_i(argv, 0)) == NULL){
clicon_err(OE_PLUGIN, 0, "%s: Error when accessing argument <db>"); clicon_err(OE_PLUGIN, 0, "%s: Error when accessing argument <db>");
goto done; goto done;
@ -141,34 +153,46 @@ expand_dbvar(void *h,
if (api_path_fmt2xpath(api_path, cvv, &xpath) < 0) if (api_path_fmt2xpath(api_path, cvv, &xpath) < 0)
goto done; goto done;
/* XXX read whole configuration, why not send xpath? */ /* XXX read whole configuration, why not send xpath? */
if (clicon_rpc_get_config(h, dbstr, xpath, &xt) < 0) if (clicon_rpc_get_config(h, dbstr, "/", &xt) < 0)
goto done; goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
clicon_rpc_generate_error(xerr); clicon_rpc_generate_error(xerr);
goto done; goto done;
} }
#if 0 xcur = xt; /* default top-of-tree */
/* Get xpath from datastore? xpathcur = xpath;
* 1. Get whole datastore, /* Create config top-of-tree */
* 2. Add tentative my location to xpath, if ((xtop = xml_new("config", NULL)) == NULL)
* 3. If leafref, compute relative xpath goto done;
*/ xbot = xtop;
{ if (api_path && api_path2xml(api_path, yspec, xtop, &xbot, &y) < 0)
cxobj *xcur = NULL; /* xpath, NULL if datastore */ goto done;
// yang_node *y = NULL; /* yang spec of xpath */ /* Special case for leafref. Detect leafref via Yang-type,
* Get Yang path element, tentatively add the new syntax to the whole
if ((xcur = xpath_first(xt, xpath)) == NULL) * tree and apply the path to that.
* Last, the reference point for the xpath code below is changed to
* the point of the tentative new xml.
* Here the whole syntax tree is loaded, and it would be better to offload
* such operations to the datastore by a generic xpath function.
*/
if ((ytype = yang_find((yang_node*)y, Y_TYPE, NULL)) != NULL)
if (strcmp(ytype->ys_argument, "leafref")==0){
if ((ypath = yang_find((yang_node*)ytype, Y_PATH, NULL)) == NULL){
clicon_err(OE_DB, 0, "Leafref %s requires path statement", ytype->ys_argument);
goto done; goto done;
} }
#endif xpathcur = ypath->ys_argument;
if (xml_merge(xt, xtop, yspec) < 0)
goto done;
if ((xcur = xpath_first(xt, xpath)) == NULL){
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
goto done;
}
}
/* One round to detect duplicates /* One round to detect duplicates
* XXX The code below would benefit from some cleanup
*/ */
j = 0; j = 0;
if (xpath_vec(xt, xpath, &xvec, &xlen) < 0) if (xpath_vec(xcur, xpathcur, &xvec, &xlen) < 0)
goto done; goto done;
for (i = 0; i < xlen; i++) { for (i = 0; i < xlen; i++) {
char *str; char *str;
@ -211,6 +235,8 @@ expand_dbvar(void *h,
done: done:
if (xvec) if (xvec)
free(xvec); free(xvec);
if (xtop)
xml_free(xtop);
if (xt) if (xt)
xml_free(xt); xml_free(xt);
if (xpath) if (xpath)

View file

@ -37,14 +37,14 @@ module ietf-ip{
} }
leaf address { leaf address {
type leafref { type leafref {
path "../../interface[name = current()/../ifname]" path "../../interface[name=eth0]"
+ "/address/ip"; + "/address/ip";
} }
} }
} }
} }
EOF EOF
# path "../../interface[name = current()/../ifname]"
# kill old backend (if any) # kill old backend (if any)
new "kill old backend" new "kill old backend"