From 05da8ef3c161eff7a351bce955fc247e4d948a26 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sun, 23 Apr 2023 17:32:06 +0200 Subject: [PATCH] Add mount-point aware code to cli_auto_show Revert patch in xpath2canonical for mountpoints --- apps/cli/cli_generate.c | 9 ++++++++- apps/cli/cli_show.c | 35 ++++++++++++++++++++++++++++------- lib/src/clixon_xpath.c | 9 ++++++--- test/test_xpath_canonical.sh | 8 +++++--- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index 35ba68b5..3bb1f45f 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -109,7 +109,12 @@ You can see which CLISPEC it generates via clixon_cli -D 2: /* variable expand function */ #define GENERATE_EXPAND_XMLDB "expand_dbvar" -/*! Create cligen variable expand entry with xmlkey format string as argument +/*! Create cligen variable expand entry with api-pathfmt format string as argument + * + * Add api-fmt as first argument to callback, eg: + * /ex:table + * Then if mountpoint add special entry: + * /ctrl:dev/ctrl:config * @param[in] h Clixon handle * @param[in] ys yang_stmt of the node at hand * @param[in] cvtype Type of the cligen variable @@ -1353,6 +1358,8 @@ yang2cli_post(clicon_handle h, /*! Generate clispec for all modules in yspec (except excluded) * + * Called in cli main function for top-level yangs. But may also be called dynamically for + * mountpoints. * @param[in] h Clixon handle * @param[in] yspec Top-level Yang statement of type Y_SPEC * @param[in] treename Name of tree diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index 9e8e4b5d..83f8280b 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -839,6 +839,7 @@ int cli_show_version(clicon_handle h, * @param[in] cvv Vector of variables from CLIgen command-line * @param[in] argv String vector of show options, format: * Generated API PATH (this is added implicitly, not actually given in the cvv) + * [] Extra api-path from mount-point * Name of datastore, such as "running" * -- from here optional: * "text"|"xml"|"json"|"cli"|"netconf" (see format_enum), default: xml @@ -879,17 +880,26 @@ cli_show_auto(clicon_handle h, char *extdefault = NULL; /* with extended tagged modes */ int argc = 0; char *xpath = NULL; - yang_stmt *yspec; + yang_stmt *yspec0; char *api_path = NULL; int cvvi = 0; char *api_path_fmt; /* xml key format */ - + char *api_path_fmt01 = NULL; + char *str; + char *mtpoint = NULL; + if (cvec_len(argv) < 2 || cvec_len(argv) > 7){ clicon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected:: * [ ]", cvec_len(argv)); goto done; } api_path_fmt = cv_string_get(cvec_i(argv, argc++)); - dbname = cv_string_get(cvec_i(argv, argc++)); + str = cv_string_get(cvec_i(argv, argc++)); + if (str && str[0] == '/'){ /* ad-hoc to see if 2nd arg is mountpoint */ + mtpoint = str; + dbname = cv_string_get(cvec_i(argv, argc++)); + } + else + dbname = str; if (cvec_len(argv) > argc) if (cli_show_option_format(argv, argc++, &format) < 0) goto done; @@ -910,13 +920,22 @@ cli_show_auto(clicon_handle h, if (cvec_len(argv) > argc){ prepend = cv_string_get(cvec_i(argv, argc++)); } - if ((yspec = clicon_dbspec_yang(h)) == NULL){ + if ((yspec0 = clicon_dbspec_yang(h)) == NULL){ clicon_err(OE_FATAL, 0, "No DB_SPEC"); goto done; } - if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path, &cvvi) < 0) - goto done; - if (api_path2xpath(api_path, yspec, &xpath, &nsc, NULL) < 0) + if (mtpoint){ + /* 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) + goto done; + } + else{ + if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path, &cvvi) < 0) + goto done; + } + if (api_path2xpath(api_path, yspec0, &xpath, &nsc, NULL) < 0) goto done; if (xpath == NULL){ clicon_err(OE_FATAL, 0, "Invalid api-path-fmt: %s", api_path_fmt); @@ -928,6 +947,8 @@ cli_show_auto(clicon_handle h, goto done; retval = 0; done: + if (api_path_fmt01) + free(api_path_fmt01); if (nsc) xml_nsctx_free(nsc); if (xpath) diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index d3408c83..dae205c9 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -969,7 +969,6 @@ xpath_vec_bool(cxobj *xcur, * @retval 1 OK with nsc1 containing the transformed nsc * @retval 0 XPath failure with reason set to why * @retval -1 Fatal Error - * XXX Detects mountpoint but is not mountpoint aware, just copies prefixes */ static int xpath_traverse_canonical(xpath_tree *xs, @@ -1005,6 +1004,7 @@ xpath_traverse_canonical(xpath_tree *xs, goto fail; } if ((ymod = yang_find_module_by_namespace(yspec, namespace)) == NULL){ +#if 0 /* Just accept it, see note in xpath2canonical */ if ((cb = cbuf_new()) == NULL){ clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; @@ -1013,12 +1013,11 @@ xpath_traverse_canonical(xpath_tree *xs, if (reason) *reason = cb; goto fail; +#endif } -#if 0 /* safe-catch if previous check is not considered as an error */ if (ymod == NULL) prefix1 = prefix0; else -#endif if ((prefix1 = yang_find_myprefix(ymod)) == NULL){ if ((cb = cbuf_new()) == NULL){ clicon_err(OE_UNIX, errno, "cbuf_new"); @@ -1093,6 +1092,10 @@ xpath_traverse_canonical(xpath_tree *xs, * if (xpath1) free(xpath1); * if (nsc1) xml_nsctx_free(nsc1); * @endcode + * @note Unsolvable issue of mountpoints, eg an xpath of //x:foo where foo is under one or several + * mointpoints: a well-defined namespace cannot be determined. Therefore just allow + * inconsistencies and hope that it will be covered by other code + * @see xpath2xml */ int xpath2canonical(const char *xpath0, diff --git a/test/test_xpath_canonical.sh b/test/test_xpath_canonical.sh index 9e8fb733..81fbae58 100755 --- a/test/test_xpath_canonical.sh +++ b/test/test_xpath_canonical.sh @@ -56,9 +56,11 @@ expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[.='42']" -n i:urn:example: new "xpath canonical form descendants" expectpart "$($clixon_util_xpath -c -y $ydir -p "//x[.='42']" -n null:urn:example:a -n j:urn:example:b)" 0 "//a:x\[.='42'\]" '0 : a = "urn:example:a"' -new "xpath canonical form (no default should fail)" -expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b 2>&1)" 0 "/x/j:y: No namespace found for prefix" - +if false; then +# No, with mointpoints I cant fail unknown prefix, see comment in xpath2canonical + new "xpath canonical form (no default should fail)" + expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b 2>&1)" 0 "/x/j:y: No namespace found for prefix" +fi new "xpath canonical form (wrong namespace should fail)" expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b 2>&1)" 0 "/i:x/j:y: No yang found for namespace"