summaryrefslogtreecommitdiff
path: root/lib/northbound_cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/northbound_cli.c')
-rw-r--r--lib/northbound_cli.c54
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);