diff options
Diffstat (limited to 'lib/northbound_cli.c')
| -rw-r--r-- | lib/northbound_cli.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index a15fe3d1c9..07e8c9dff9 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -84,20 +84,12 @@ void nb_cli_enqueue_change(struct vty *vty, const char *xpath, int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) { - struct nb_config *candidate_transitory; char xpath_base[XPATH_MAXLEN] = {}; bool error = false; int ret; VTY_CHECK_XPATH; - /* - * Create a copy of the candidate configuration. For consistency, we - * need to ensure that either all changes made by the command are - * accepted or none are. - */ - candidate_transitory = nb_config_dup(vty->candidate_config); - /* Parse the base XPath format string. */ if (xpath_base_fmt) { va_list ap; @@ -137,7 +129,7 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH, "%s: unknown data path: %s", __func__, xpath); error = true; - break; + continue; } /* If the value is not set, get the default if it exists. */ @@ -149,7 +141,7 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) * Ignore "not found" errors when editing the candidate * configuration. */ - ret = nb_candidate_edit(candidate_transitory, nb_node, + ret = nb_candidate_edit(vty->candidate_config, nb_node, change->operation, xpath, NULL, data); yang_data_free(data); if (ret != NB_OK && ret != NB_ERR_NOT_FOUND) { @@ -159,29 +151,20 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) __func__, nb_operation_name(change->operation), xpath); error = true; - break; + continue; } } if (error) { - nb_config_free(candidate_transitory); - - switch (frr_get_cli_mode()) { - case FRR_CLI_CLASSIC: - vty_out(vty, "%% Configuration failed.\n\n"); - break; - case FRR_CLI_TRANSACTIONAL: - vty_out(vty, - "%% Failed to edit candidate configuration.\n\n"); - break; - } + /* + * Failure to edit the candidate configuration should never + * happen in practice, unless there's a bug in the code. When + * that happens, log the error but otherwise ignore it. + */ + vty_out(vty, "%% Failed to edit configuration.\n\n"); vty_show_libyang_errors(vty, ly_native_ctx); - - return CMD_WARNING_CONFIG_FAILED; } - nb_config_replace(vty->candidate_config, candidate_transitory, false); - /* Do an implicit "commit" when using the classic CLI mode. */ if (frr_get_cli_mode() == FRR_CLI_CLASSIC) { ret = nb_candidate_commit(vty->candidate_config, NB_CLIENT_CLI, @@ -438,6 +421,23 @@ static struct lyd_node *ly_iter_next_up(const struct lyd_node *elem) return elem->parent; } +/* Prepare the configuration for display. */ +void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults) +{ + lyd_schema_sort(config->dnode, 1); + + /* + * When "with-defaults" is used, call lyd_validate() only to create + * default child nodes, ignoring any possible validation error. This + * doesn't need to be done when displaying the running configuration + * since it's always fully validated. + */ + if (with_defaults && config != running_config) + (void)lyd_validate(&config->dnode, + LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, + ly_native_ctx); +} + void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *root, bool with_defaults) { @@ -530,6 +530,8 @@ static int nb_cli_show_config(struct vty *vty, struct nb_config *config, struct yang_translator *translator, bool with_defaults) { + nb_cli_show_config_prepare(config, with_defaults); + switch (format) { case NB_CFG_FMT_CMDS: nb_cli_show_config_cmds(vty, config, with_defaults); |
