]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #13320 from LabNConsulting/fix-show-opdata-command
authorDonatas Abraitis <donatas@opensourcerouting.org>
Mon, 17 Apr 2023 11:51:38 +0000 (14:51 +0300)
committerGitHub <noreply@github.com>
Mon, 17 Apr 2023 11:51:38 +0000 (14:51 +0300)
Fix show opdata command

lib/northbound.c
lib/northbound_cli.c
lib/northbound_sysrepo.c
lib/yang.c
lib/yang.h
lib/yang_translator.c
lib/yang_wrappers.c
tests/topotests/lib/topogen.py
tests/topotests/lib/topotest.py
tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py

index 307cf0fb496abf840e571d2087351424e47c2d11..775f6ff92f9494352f3dbe3c97f374887b2df392 100644 (file)
@@ -167,7 +167,7 @@ struct nb_node *nb_node_find(const char *path)
         * Use libyang to find the schema node associated to the path and get
         * the northbound node from there (snode private pointer).
         */
-       snode = lys_find_path(ly_native_ctx, NULL, path, 0);
+       snode = yang_find_snode(ly_native_ctx, path, 0);
        if (!snode)
                return NULL;
 
@@ -2129,8 +2129,8 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
         * all YANG lists (if any).
         */
 
-       LY_ERR err = lyd_new_path(NULL, ly_native_ctx, xpath, NULL,
-                                 LYD_NEW_PATH_UPDATE, &dnode);
+       LY_ERR err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0,
+                                  LYD_NEW_PATH_UPDATE, NULL, &dnode);
        if (err || !dnode) {
                const char *errmsg =
                        err ? ly_errmsg(ly_native_ctx) : "node not found";
index 5cf5f93b437c51ed3161423c951a5f3a684056b8..c5582fc21c2338edb3036e28a00cf75ed32d14cf 100644 (file)
@@ -1434,6 +1434,7 @@ DEFPY (show_yang_operational_data,
        struct lyd_node *dnode;
        char *strp;
        uint32_t print_options = LYD_PRINT_WITHSIBLINGS;
+       int ret;
 
        if (xml)
                format = LYD_XML;
@@ -1454,10 +1455,15 @@ DEFPY (show_yang_operational_data,
 
        /* Obtain data. */
        dnode = yang_dnode_new(ly_ctx, false);
-       if (nb_oper_data_iterate(xpath, translator, 0, nb_cli_oper_data_cb,
-                                dnode)
-           != NB_OK) {
-               vty_out(vty, "%% Failed to fetch operational data.\n");
+       ret = nb_oper_data_iterate(xpath, translator, 0, nb_cli_oper_data_cb,
+                                  dnode);
+       if (ret != NB_OK) {
+               if (format == LYD_JSON)
+                       vty_out(vty, "{}\n");
+               else {
+                       /* embed ly_last_errmsg() when we get newer libyang */
+                       vty_out(vty, "<!-- Not found -->\n");
+               }
                yang_dnode_free(dnode);
                return CMD_WARNING;
        }
index 86105d2e77b7ad9850cbbe8db333eee892dd356f..7fd4af83562f99ba743aeeb05de6db60e9b44033 100644 (file)
@@ -357,7 +357,7 @@ static int frr_sr_state_data_iter_cb(const struct lysc_node *snode,
        ly_errno = 0;
        ly_errno = lyd_new_path(NULL, ly_native_ctx, data->xpath, data->value,
                                0, &dnode);
-       if (!dnode && ly_errno) {
+       if (ly_errno) {
                flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed",
                          __func__);
                yang_data_free(data);
index 70a3251ab39db4280c8c3a904fac85d7febee71b..4dd8654217183cfcdec1d41abf4c14cb689f2d5c 100644 (file)
@@ -250,6 +250,23 @@ void yang_snode_get_path(const struct lysc_node *snode,
        }
 }
 
+struct lysc_node *yang_find_snode(struct ly_ctx *ly_ctx, const char *xpath,
+                                 uint32_t options)
+{
+       struct lysc_node *snode;
+       struct ly_set *set;
+       LY_ERR err;
+
+       err = lys_find_xpath(ly_native_ctx, NULL, xpath, options, &set);
+       if (err || !set->count)
+               return NULL;
+
+       snode = set->snodes[0];
+       ly_set_free(set, NULL);
+
+       return snode;
+}
+
 struct lysc_node *yang_snode_real_parent(const struct lysc_node *snode)
 {
        struct lysc_node *parent = snode->parent;
index 654c246f0dc99f47e3e0110ad091d628199a832b..37369c09bf81b735603358ed8d95936f7c1a8145 100644 (file)
@@ -210,6 +210,27 @@ extern void yang_snode_get_path(const struct lysc_node *snode,
                                enum yang_path_type type, char *xpath,
                                size_t xpath_len);
 
+
+/*
+ * Find libyang schema node for the given xpath. Uses `lys_find_xpath`,
+ * returning only the first of a set of nodes -- normally there should only
+ * be one.
+ *
+ * ly_ctx
+ *    libyang context to operate on.
+ *
+ * xpath
+ *    XPath expression (absolute or relative) to find the schema node for.
+ *
+ * options
+ *    Libyang findxpathoptions value (see lys_find_xpath).
+ *
+ * Returns:
+ *    The libyang schema node if found, or NULL if not found.
+ */
+extern struct lysc_node *yang_find_snode(struct ly_ctx *ly_ctx,
+                                        const char *xpath, uint32_t options);
+
 /*
  * Find first parent schema node which is a presence-container or a list
  * (non-presence containers are ignored).
index de668230abe63edd868f564d40a541d719bdf811..eae7577a0d1c2c905261a9c211c73deb283f08dc 100644 (file)
@@ -235,8 +235,8 @@ struct yang_translator *yang_translator_load(const char *path)
                xpath_custom =
                        yang_dnode_get_string(set->dnodes[i], "./custom");
 
-               snode_custom = lys_find_path(translator->ly_ctx, NULL,
-                                            xpath_custom, 0);
+               snode_custom =
+                       yang_find_snode(translator->ly_ctx, xpath_custom, 0);
                if (!snode_custom) {
                        flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
                                  "%s: unknown data path: %s", __func__,
@@ -247,8 +247,7 @@ struct yang_translator *yang_translator_load(const char *path)
 
                xpath_native =
                        yang_dnode_get_string(set->dnodes[i], "./native");
-               snode_native =
-                       lys_find_path(ly_native_ctx, NULL, xpath_native, 0);
+               snode_native = yang_find_snode(ly_native_ctx, xpath_native, 0);
                if (!snode_native) {
                        flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
                                  "%s: unknown data path: %s", __func__,
@@ -315,7 +314,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,
        else
                ly_ctx = ly_native_ctx;
 
-       snode = lys_find_path(ly_ctx, NULL, xpath, 0);
+       snode = yang_find_snode(ly_ctx, xpath, 0);
        if (!snode) {
                flog_warn(EC_LIB_YANG_TRANSLATION_ERROR,
                          "%s: unknown data path: %s", __func__, xpath);
index 509c4dd8560cbfa41dcd9cc603fdbc13f612935e..dc049a374a9e47ad19ec19e917f61af27d45c64e 100644 (file)
@@ -89,7 +89,7 @@ static const char *yang_get_default_value(const char *xpath)
        const struct lysc_node *snode;
        const char *value;
 
-       snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
+       snode = yang_find_snode(ly_native_ctx, xpath, 0);
        if (snode == NULL) {
                flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
                         "%s: unknown data path: %s", __func__, xpath);
@@ -206,7 +206,7 @@ int yang_str2enum(const char *xpath, const char *value)
        const struct lysc_type_enum *type;
        const struct lysc_type_bitenum_item *enums;
 
-       snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
+       snode = yang_find_snode(ly_native_ctx, xpath, 0);
        if (snode == NULL) {
                flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
                         "%s: unknown data path: %s", __func__, xpath);
@@ -241,7 +241,7 @@ struct yang_data *yang_data_new_enum(const char *xpath, int value)
        const struct lysc_type_enum *type;
        const struct lysc_type_bitenum_item *enums;
 
-       snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
+       snode = yang_find_snode(ly_native_ctx, xpath, 0);
        if (snode == NULL) {
                flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
                         "%s: unknown data path: %s", __func__, xpath);
index f5b3ad06d94db26fb8b077f955a7d13faf809944..d505317e4e2fe5b5c3a12e16646df7d4be43aace 100644 (file)
@@ -33,6 +33,7 @@ import os
 import platform
 import pwd
 import re
+import shlex
 import subprocess
 import sys
 from collections import OrderedDict
@@ -946,9 +947,11 @@ class TopoRouter(TopoGear):
         if daemon is not None:
             dparam += "-d {}".format(daemon)
 
-        vtysh_command = 'vtysh {} -c "{}" 2>/dev/null'.format(dparam, command)
+        vtysh_command = "vtysh {} -c {} 2>/dev/null".format(
+            dparam, shlex.quote(command)
+        )
 
-        self.logger.debug('vtysh command => "{}"'.format(command))
+        self.logger.debug("vtysh command => {}".format(shlex.quote(command)))
         output = self.run(vtysh_command)
 
         dbgout = output.strip()
index 86a7f2000f3a683af86f7ee8bf12f322b5c08814..ef04d59e29d65ca2ac268199543e9482427149b8 100644 (file)
@@ -1840,6 +1840,8 @@ class Router(Node):
                 logger.info(
                     "%s: %s %s launched in gdb window", self, self.routertype, daemon
                 )
+                # Need better check for daemons running.
+                time.sleep(5)
             else:
                 if daemon != "snmpd":
                     cmdopt += " -d "
index b0ba1469842fe95da9d1827f173a46bf4b446806..acc0aea9e894bebc92baf27c0ff4082b91c60268 100644 (file)
@@ -52,9 +52,17 @@ def test_rip_allow_ecmp():
     r1 = tgen.gears["r1"]
 
     def _show_rip_routes():
-        output = json.loads(
-            r1.vtysh_cmd("show yang operational-data /frr-ripd:ripd ripd")
+        xpath = (
+            "/frr-ripd:ripd/instance[vrf='default']"
+            "/state/routes/route[prefix='10.10.10.1/32']"
         )
+        try:
+            output = json.loads(
+                r1.vtysh_cmd(f"show yang operational-data {xpath} ripd")
+            )
+        except Exception:
+            return False
+
         try:
             output = output["frr-ripd:ripd"]["instance"][0]["state"]["routes"]
         except KeyError: