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
|
# 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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
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)
|
||||||
cxobj *xcur = NULL; /* xpath, NULL if datastore */
|
if (strcmp(ytype->ys_argument, "leafref")==0){
|
||||||
// yang_node *y = NULL; /* yang spec of xpath */
|
if ((ypath = yang_find((yang_node*)ytype, Y_PATH, NULL)) == NULL){
|
||||||
|
clicon_err(OE_DB, 0, "Leafref %s requires path statement", ytype->ys_argument);
|
||||||
if ((xcur = xpath_first(xt, xpath)) == NULL)
|
goto done;
|
||||||
goto done;
|
}
|
||||||
|
xpathcur = ypath->ys_argument;
|
||||||
|
if (xml_merge(xt, xtop, yspec) < 0)
|
||||||
}
|
goto done;
|
||||||
#endif
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue