diff --git a/doc/user/basic.rst b/doc/user/basic.rst index 4c196cfcfe..ea4b3f41f3 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -678,6 +678,20 @@ Terminal Mode Commands This command displays FRR's timer data for timers that will pop in the future. +.. clicmd:: show yang operational-data XPATH [{format |translate TRANSLATOR|with-config}] DAEMON + + Display the YANG operational data starting from XPATH. The default + format is JSON, but can be displayed in XML as well. + + Normally YANG operational data are located inside containers marked + as `read-only`. + + Optionally it is also possible to display configuration leaves in + addition to operational data with the option `with-config`. This + option enables the display of configuration leaves with their + currently configured value (if the leaf is optional it will only show + if it was created or has a default value). + .. _common-invocation-options: Common Invocation Options diff --git a/lib/northbound.c b/lib/northbound.c index 49adea6d53..2cc7ac6ea1 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -1649,10 +1649,12 @@ static int nb_oper_data_iter_container(const struct nb_node *nb_node, uint32_t flags, nb_oper_data_cb cb, void *arg) { + const struct lysc_node *snode = nb_node->snode; + if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY)) return NB_OK; - /* Presence containers. */ + /* Read-only presence containers. */ if (nb_node->cbs.get_elem) { struct yang_data *data; int ret; @@ -1662,15 +1664,24 @@ static int nb_oper_data_iter_container(const struct nb_node *nb_node, /* Presence container is not present. */ return NB_OK; - ret = (*cb)(nb_node->snode, translator, data, arg); + ret = (*cb)(snode, translator, data, arg); if (ret != NB_OK) return ret; } + /* Read-write presence containers. */ + if (CHECK_FLAG(snode->flags, LYS_CONFIG_W)) { + struct lysc_node_container *scontainer; + + scontainer = (struct lysc_node_container *)snode; + if (CHECK_FLAG(scontainer->flags, LYS_PRESENCE) + && !yang_dnode_get(running_config->dnode, xpath)) + return NB_OK; + } + /* Iterate over the child nodes. */ - return nb_oper_data_iter_children(nb_node->snode, xpath, list_entry, - list_keys, translator, false, flags, - cb, arg); + return nb_oper_data_iter_children(snode, xpath, list_entry, list_keys, + translator, false, flags, cb, arg); } static int diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 1e25f6a1e2..56eac9dc32 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -1464,6 +1464,7 @@ DEFPY (show_yang_operational_data, [{\ format \ |translate WORD$translator_family\ + |with-config$with_config\ }]", SHOW_STR "YANG information\n" @@ -1473,13 +1474,15 @@ DEFPY (show_yang_operational_data, "JavaScript Object Notation\n" "Extensible Markup Language\n" "Translate operational data\n" - "YANG module translator\n") + "YANG module translator\n" + "Merge configuration data\n") { LYD_FORMAT format; struct yang_translator *translator = NULL; struct ly_ctx *ly_ctx; struct lyd_node *dnode; char *strp; + uint32_t print_options = LYD_PRINT_WITHSIBLINGS; if (xml) format = LYD_XML; @@ -1507,13 +1510,21 @@ DEFPY (show_yang_operational_data, yang_dnode_free(dnode); return CMD_WARNING; } + + if (with_config && yang_dnode_exists(running_config->dnode, xpath)) { + struct lyd_node *config_dnode = + yang_dnode_get(running_config->dnode, xpath); + if (config_dnode != NULL) { + lyd_merge_tree(&dnode, yang_dnode_dup(config_dnode), + LYD_MERGE_DESTRUCT); + print_options |= LYD_PRINT_WD_ALL; + } + } + (void)lyd_validate_all(&dnode, ly_ctx, 0, NULL); /* Display the data. */ - if (lyd_print_mem(&strp, dnode, format, - LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL) - != 0 - || !strp) { + if (lyd_print_mem(&strp, dnode, format, print_options) != 0 || !strp) { vty_out(vty, "%% Failed to display operational data.\n"); yang_dnode_free(dnode); return CMD_WARNING; diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index ed1f1fb5bb..9e8f73b101 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2955,6 +2955,7 @@ DEFUN (show_yang_operational_data, [{\ format \ |translate WORD\ + |with-config\ }]" DAEMONS_LIST, SHOW_STR "YANG information\n" @@ -2965,6 +2966,7 @@ DEFUN (show_yang_operational_data, "Extensible Markup Language\n" "Translate operational data\n" "YANG module translator\n" + "Merge configuration data\n" DAEMONS_STR) { return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);