Added yspec parameter to api_path_fmt2api_path()
Added "%k" as extra flag character to api-path-fmt
This commit is contained in:
parent
96f94114e2
commit
9f73014500
9 changed files with 98 additions and 21 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Clixon Changelog
|
||||
|
||||
* [6.6.0](#660) Expected: February 2024
|
||||
* [6.6.0](#660) Expected: March 2024
|
||||
* [6.5.0](#650) 6 December 2023
|
||||
* [6.4.0](#640) 30 September 2023
|
||||
* [6.3.0](#630) 29 July 2023
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* [6.0.0](#600) 29 Nov 2022
|
||||
|
||||
## 6.6.0
|
||||
Expected: February 2024
|
||||
Expected: March 2024
|
||||
|
||||
### Minor features
|
||||
|
||||
|
|
@ -33,6 +33,7 @@ Expected: February 2024
|
|||
* Filtered state data if not match xpath
|
||||
* Added reference count for shared yang-specs (schema mounts)
|
||||
* Allowed for sharing yspec+modules between several mountpoints
|
||||
* Added "%k" as extra flag character to api-path-fmt
|
||||
|
||||
### API changes on existing protocol/config features
|
||||
Users may have to change how they access the system
|
||||
|
|
@ -51,6 +52,8 @@ Users may have to change how they access the system
|
|||
### C/CLI-API changes on existing features
|
||||
Developers may need to change their code
|
||||
|
||||
* Added `yspec` parameter to `api_path_fmt2api_path()`:
|
||||
* `api_path_fmt2api_path(af, c, a, c)` --> `api_path_fmt2api_path(af, c, yspec, a, c)`
|
||||
* Added flags parameter to default functions:
|
||||
* `xml_default_recurse(...)` -> `xml_default_recurse(..., 0)`
|
||||
* `xml_defaults_nopresence(...)` -> `xml_default_nopresence(..., 0)`
|
||||
|
|
|
|||
|
|
@ -128,11 +128,16 @@ cli_auto_edit(clixon_handle h,
|
|||
int argc = 0;
|
||||
char *str;
|
||||
char *mtpoint = NULL;
|
||||
yang_stmt *yspec0;
|
||||
|
||||
if (cvec_len(argv) != 2 && cvec_len(argv) != 3){
|
||||
clixon_err(OE_PLUGIN, EINVAL, "Usage: %s(api_path_fmt>*, <treename>)", __FUNCTION__);
|
||||
goto done;
|
||||
}
|
||||
if ((yspec0 = clicon_dbspec_yang(h)) == NULL){
|
||||
clixon_err(OE_FATAL, 0, "No DB_SPEC");
|
||||
goto done;
|
||||
}
|
||||
api_path_fmt = cv_string_get(cvec_i(argv, argc++));
|
||||
str = cv_string_get(cvec_i(argv, argc++));
|
||||
if (str && strncmp(str, "mtpoint:", strlen("mtpoint:")) == 0){
|
||||
|
|
@ -172,7 +177,7 @@ cli_auto_edit(clixon_handle h,
|
|||
goto done;
|
||||
}
|
||||
/* get api-path and xpath */
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv2, &api_path, NULL) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv2, yspec0, &api_path, NULL) < 0)
|
||||
goto done;
|
||||
/* Store this as edit-mode */
|
||||
if (clicon_data_set(h, "cli-edit-mode", api_path) < 0)
|
||||
|
|
@ -234,11 +239,16 @@ cli_auto_up(clixon_handle h,
|
|||
int j;
|
||||
size_t len;
|
||||
cvec *cvv_filter = NULL;
|
||||
yang_stmt *yspec0;
|
||||
|
||||
if (cvec_len(argv) != 1){
|
||||
clixon_err(OE_PLUGIN, EINVAL, "Usage: %s(<treename>)", __FUNCTION__);
|
||||
goto done;
|
||||
}
|
||||
if ((yspec0 = clicon_dbspec_yang(h)) == NULL){
|
||||
clixon_err(OE_FATAL, 0, "No DB_SPEC");
|
||||
goto done;
|
||||
}
|
||||
cv = cvec_i(argv, 0);
|
||||
treename = cv_string_get(cv);
|
||||
if ((ph = cligen_ph_find(cli_cligen(h), treename)) == NULL){
|
||||
|
|
@ -289,7 +299,7 @@ cli_auto_up(clixon_handle h,
|
|||
cvec_append_var(cvv1, cv);
|
||||
}
|
||||
/* get api-path and xpath */
|
||||
if (api_path_fmt2api_path(api_path_fmt1, cvv1, &api_path, NULL) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt1, cvv1, yspec0, &api_path, NULL) < 0)
|
||||
goto done;
|
||||
/* Store this as edit-mode */
|
||||
clicon_data_set(h, "cli-edit-mode", api_path);
|
||||
|
|
@ -506,11 +516,16 @@ cli_auto_sub_enter(clixon_handle h,
|
|||
cg_var *cv = NULL;
|
||||
pt_head *ph;
|
||||
struct findpt_arg fa = {0,};
|
||||
yang_stmt *yspec0;
|
||||
|
||||
if (cvec_len(argv) < 2){
|
||||
clixon_err(OE_PLUGIN, EINVAL, "Usage: %s(<tree> <api_path_fmt> (,vars)*)", __FUNCTION__);
|
||||
goto done;
|
||||
}
|
||||
if ((yspec0 = clicon_dbspec_yang(h)) == NULL){
|
||||
clixon_err(OE_FATAL, 0, "No DB_SPEC");
|
||||
goto done;
|
||||
}
|
||||
/* First argv argument: treename */
|
||||
cv = cvec_i(argv, 0);
|
||||
treename = cv_string_get(cv);
|
||||
|
|
@ -540,7 +555,7 @@ cli_auto_sub_enter(clixon_handle h,
|
|||
if (cvec_append_var(cvv1, cvec_i(cvv, i)) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv1, &api_path, NULL) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv1, yspec0, &api_path, NULL) < 0)
|
||||
goto done;
|
||||
/* Assign the variables */
|
||||
if ((cvv2 = cvec_append(clicon_data_cvec_get(h, "cli-edit-cvv"), cvv1)) == NULL)
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ cli_dbxml(clixon_handle h,
|
|||
/* Transform template format string + cvv to actual api-path
|
||||
* cvvi indicates if all cvv entries were used
|
||||
*/
|
||||
if (api_path_fmt2api_path(api_path_fmt01, cvv, &api_path, &cvvi) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt01, cvv, yspec0, &api_path, &cvvi) < 0)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
|
|
@ -451,7 +451,7 @@ cli_dbxml(clixon_handle h,
|
|||
/* Transform template format string + cvv to actual api-path
|
||||
* cvvi indicates if all cvv entries were used
|
||||
*/
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path, &cvvi) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv, yspec0, &api_path, &cvvi) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Create config top-of-tree */
|
||||
|
|
|
|||
|
|
@ -204,7 +204,8 @@ xpath_append(cbuf *cb0,
|
|||
* @retval -1 Error
|
||||
* @see cli_expand_var_generate where api_path_fmt + mt-point are generated
|
||||
* The syntax of <api_path_fmt> is of RFC8040 api-path with the following extension:
|
||||
* "%s" represents the values of cvv in order starting from element 1
|
||||
* %s Represents the values of cvv in order starting from element 1
|
||||
* %k Represents the (first) key of the (previous) list
|
||||
*/
|
||||
int
|
||||
expand_dbvar(void *h,
|
||||
|
|
@ -297,11 +298,11 @@ expand_dbvar(void *h,
|
|||
/* Get and combined api-path01 */
|
||||
if (mtpoint_paths(yspec0, mtpoint, api_path_fmt, &api_path_fmt01) < 0)
|
||||
goto done;
|
||||
if (api_path_fmt2api_path(api_path_fmt01, cvv, &api_path, &cvvi) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt01, cvv, yspec0, &api_path, &cvvi) < 0)
|
||||
goto done;
|
||||
}
|
||||
else{
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path, &cvvi) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv, yspec0, &api_path, &cvvi) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (api_path == NULL)
|
||||
|
|
@ -1092,11 +1093,11 @@ cli_show_auto(clixon_handle h,
|
|||
/* Get and combined api-path01 */
|
||||
if (mtpoint_paths(yspec0, mtpoint, api_path_fmt, &api_path_fmt01) < 0)
|
||||
goto done;
|
||||
if (api_path_fmt2api_path(api_path_fmt01, cvv, &api_path, &cvvi) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt01, cvv, yspec0, &api_path, &cvvi) < 0)
|
||||
goto done;
|
||||
}
|
||||
else{
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path, &cvvi) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvv, yspec0, &api_path, &cvvi) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (api_path2xpath(api_path, yspec0, &xpath, &nsc, NULL) < 0)
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ snmp_yang2xml(cxobj *xtop,
|
|||
}
|
||||
for (i=0; i<cvec_len(cvk); i++)
|
||||
cvec_append_var(cvk1, cvec_i(cvk,i));
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvk1, &api_path, NULL) < 0)
|
||||
if (api_path_fmt2api_path(api_path_fmt, cvk1, yspec, &api_path, NULL) < 0)
|
||||
goto done;
|
||||
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, xbot, NULL, NULL)) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ typedef struct {
|
|||
int clixon_path_free(clixon_path *cplist);
|
||||
int xml_yang_root(cxobj *x, cxobj **xr);
|
||||
int yang2api_path_fmt(yang_stmt *ys, int inclkey, char **api_path_fmt);
|
||||
int api_path_fmt2api_path(const char *api_path_fmt, cvec *cvv, char **api_path, int *cvvi);
|
||||
int api_path_fmt2api_path(const char *api_path_fmt, cvec *cvv, yang_stmt *yspec, char **api_path, int *cvvi);
|
||||
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_path2xml(char *api_path, yang_stmt *yspec, cxobj *xtop,
|
||||
|
|
|
|||
|
|
@ -435,6 +435,50 @@ yang2api_path_fmt(yang_stmt *ys,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Sub-function to expandvar to replace ${key} with YANG list keyname
|
||||
*
|
||||
* An exercise in looking in YANG and adapting to clixon_str_subst()
|
||||
* @param[in,out] cb api-path buffer
|
||||
* @param[in] yspec Yang spec
|
||||
*/
|
||||
static int
|
||||
api_path_fmt_subst_list_key(cbuf *cb,
|
||||
yang_stmt *yspec)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xtop = NULL; /* xpath root */
|
||||
cxobj *xbot = NULL; /* xpath, NULL if datastore */
|
||||
yang_stmt *yres = NULL;
|
||||
cvec *cvk;
|
||||
cg_var *cvi;
|
||||
int ret;
|
||||
|
||||
if ((xtop = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
xbot = xtop;
|
||||
if ((ret = api_path2xml(cbuf_get(cb), yspec, xtop, YC_DATANODE, 0, &xbot, &yres, NULL)) < 0)
|
||||
goto done;
|
||||
if (ret != 1){
|
||||
clixon_err(OE_YANG, 0, "Invalid api_path %s or associated XML", cbuf_get(cb));
|
||||
goto done;
|
||||
}
|
||||
if (yres == NULL){
|
||||
clixon_err(OE_YANG, 0, "No YANG LIST");
|
||||
goto done;
|
||||
}
|
||||
if (yang_keyword_get(yres) != Y_LIST){
|
||||
clixon_err(OE_YANG, 0, "YANG of %s expected LIST", yang_argument_get(yres));
|
||||
goto done;
|
||||
}
|
||||
if ((cvk = yang_cvec_get(yres)) != NULL &&
|
||||
(cvi = cvec_i(cvk, 0)) != NULL){
|
||||
cprintf(cb, "%s", cv_string_get(cvi));
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Transform an xml key format and a vector of values to an XML key
|
||||
*
|
||||
* Used for actual key, eg in clicon_rpc_change(), xmldb_put_xkey()
|
||||
|
|
@ -471,6 +515,7 @@ yang2api_path_fmt(yang_stmt *ys,
|
|||
int
|
||||
api_path_fmt2api_path(const char *api_path_fmt,
|
||||
cvec *cvv,
|
||||
yang_stmt *yspec,
|
||||
char **api_path,
|
||||
int *cvv_i)
|
||||
{
|
||||
|
|
@ -498,8 +543,10 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
|||
c = api_path_fmt[i];
|
||||
if (esc){
|
||||
esc = 0;
|
||||
if (c == 's' && /* Only accept "%s" no other types */
|
||||
j != cvec_len(cvv)) { /* last element */
|
||||
switch (c){
|
||||
case 's':
|
||||
if (j == cvec_len(cvv)) /* last element */
|
||||
break;
|
||||
if ((cv = cvec_i(cvv, j++)) == NULL){
|
||||
clixon_err(OE_XML, 0, "Number of elements in cvv does not match api_path_fmt string");
|
||||
goto done;
|
||||
|
|
@ -524,6 +571,13 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
|||
free(str);
|
||||
str = NULL;
|
||||
}
|
||||
break;
|
||||
case 'k': /* list key */
|
||||
if (api_path_fmt_subst_list_key(cb, yspec) < 0)
|
||||
goto done;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uri_encode = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1216,7 +1216,7 @@ clixon_unicode2utf8(char *ucstr,
|
|||
*
|
||||
* @param[in] str Input string
|
||||
* @param[in] cvv Variable name/value vector
|
||||
* @param[out] cb Result buffer
|
||||
* @param[out] cb Result buffer (assumed created on entry)
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
|
|
@ -1234,6 +1234,10 @@ clixon_str_subst(char *str,
|
|||
char *varname;
|
||||
char *varval;
|
||||
|
||||
if (cb == NULL){
|
||||
clixon_err(OE_UNIX, EINVAL, "cb is NULL");
|
||||
goto done;
|
||||
}
|
||||
if (clixon_strsep2(str, "${", "}", &vec, &nvec) < 0)
|
||||
goto done;
|
||||
if (nvec > 1){
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ xml_diff_ordered_by_user(cxobj *x0,
|
|||
} while ((xj = xml_child_each(x1, xj, CX_ELMNT)) != NULL &&
|
||||
xml_spec(xj) == yc);
|
||||
retval = 0;
|
||||
done:
|
||||
// done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue