Added completion for generated cli leafrefs for both absolute and relatve paths.
This commit is contained in:
parent
1b6c9aacbe
commit
f995f1e268
4 changed files with 52 additions and 23 deletions
|
|
@ -1,6 +1,8 @@
|
|||
# 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
|
||||
|
||||
|
|
|
|||
|
|
@ -297,7 +297,8 @@ main(int argc, char **argv)
|
|||
char *dir = dirname(str);
|
||||
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_DIR", strdup(dir));
|
||||
clicon_option_str_set(h, "CLICON_YANG_DIR", dir);
|
||||
free(str);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -112,12 +112,24 @@ expand_dbvar(void *h,
|
|||
int j;
|
||||
int k;
|
||||
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){
|
||||
clicon_err(OE_PLUGIN, 0, "%s: requires arguments: <db> <xmlkeyfmt>",
|
||||
__FUNCTION__);
|
||||
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){
|
||||
clicon_err(OE_PLUGIN, 0, "%s: Error when accessing argument <db>");
|
||||
goto done;
|
||||
|
|
@ -141,34 +153,46 @@ expand_dbvar(void *h,
|
|||
if (api_path_fmt2xpath(api_path, cvv, &xpath) < 0)
|
||||
goto done;
|
||||
/* 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;
|
||||
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error(xerr);
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
/* Get xpath from datastore?
|
||||
* 1. Get whole datastore,
|
||||
* 2. Add tentative my location to xpath,
|
||||
* 3. If leafref, compute relative xpath
|
||||
*/
|
||||
{
|
||||
cxobj *xcur = NULL; /* xpath, NULL if datastore */
|
||||
// yang_node *y = NULL; /* yang spec of xpath */
|
||||
|
||||
if ((xcur = xpath_first(xt, xpath)) == NULL)
|
||||
xcur = xt; /* default top-of-tree */
|
||||
xpathcur = xpath;
|
||||
/* Create config top-of-tree */
|
||||
if ((xtop = xml_new("config", NULL)) == NULL)
|
||||
goto done;
|
||||
xbot = xtop;
|
||||
if (api_path && api_path2xml(api_path, yspec, xtop, &xbot, &y) < 0)
|
||||
goto done;
|
||||
/* Special case for leafref. Detect leafref via Yang-type,
|
||||
* Get Yang path element, tentatively add the new syntax to the whole
|
||||
* 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;
|
||||
|
||||
|
||||
}
|
||||
#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
|
||||
* XXX The code below would benefit from some cleanup
|
||||
*/
|
||||
j = 0;
|
||||
if (xpath_vec(xt, xpath, &xvec, &xlen) < 0)
|
||||
if (xpath_vec(xcur, xpathcur, &xvec, &xlen) < 0)
|
||||
goto done;
|
||||
for (i = 0; i < xlen; i++) {
|
||||
char *str;
|
||||
|
|
@ -211,6 +235,8 @@ expand_dbvar(void *h,
|
|||
done:
|
||||
if (xvec)
|
||||
free(xvec);
|
||||
if (xtop)
|
||||
xml_free(xtop);
|
||||
if (xt)
|
||||
xml_free(xt);
|
||||
if (xpath)
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ module ietf-ip{
|
|||
}
|
||||
leaf address {
|
||||
type leafref {
|
||||
path "../../interface[name = current()/../ifname]"
|
||||
path "../../interface[name=eth0]"
|
||||
+ "/address/ip";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# path "../../interface[name = current()/../ifname]"
|
||||
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue