summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2023-10-09 03:21:16 +0300
committerIgor Ryzhov <iryzhov@nfware.com>2024-01-11 15:06:53 +0200
commitd726114790464831b1d377eb3acc05c2933e3cd8 (patch)
treef23c3e1eaf654359d0bf28722eae92fcf5544f97
parentfe0d4dc2cb8fdf63524d92ab364157904327eb29 (diff)
mgmt, lib: implement REPLACE operation
Replace operation removes the current data node configuration and sets the provided value. As current northbound code works only with one xpath at a time, the operation only makes sense to clear the config of a container without deleting it itself. However, the next step is to allow passing JSON-encoded complex values to northbound operations which will make replace operation much more useful. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
-rw-r--r--lib/mgmt.proto1
-rw-r--r--lib/mgmt_be_client.c1
-rw-r--r--lib/northbound.c41
-rw-r--r--lib/northbound.h1
-rw-r--r--lib/vty.c5
-rw-r--r--mgmtd/mgmt_txn.c3
-rw-r--r--mgmtd/mgmt_vty.c19
7 files changed, 69 insertions, 2 deletions
diff --git a/lib/mgmt.proto b/lib/mgmt.proto
index e0b6019d2b..5d83fca347 100644
--- a/lib/mgmt.proto
+++ b/lib/mgmt.proto
@@ -58,6 +58,7 @@ enum CfgDataReqType {
REMOVE_DATA = 2;
CREATE_DATA = 3;
DELETE_DATA = 4;
+ REPLACE_DATA = 5;
}
message YangCfgDataReq {
diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c
index 53df191b2c..16aea249a4 100644
--- a/lib/mgmt_be_client.c
+++ b/lib/mgmt_be_client.c
@@ -577,6 +577,7 @@ static int mgmt_be_update_setcfg_in_batch(struct mgmt_be_client *client_ctx,
break;
case MGMTD__CFG_DATA_REQ_TYPE__SET_DATA:
case MGMTD__CFG_DATA_REQ_TYPE__CREATE_DATA:
+ case MGMTD__CFG_DATA_REQ_TYPE__REPLACE_DATA:
cfg_chg->operation = NB_OP_MODIFY;
break;
case MGMTD__CFG_DATA_REQ_TYPE__REQ_TYPE_NONE:
diff --git a/lib/northbound.c b/lib/northbound.c
index 1fd58cf8b0..efbf1bc4bc 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -691,7 +691,7 @@ int nb_candidate_edit(struct nb_config *candidate,
const struct yang_data *previous,
const struct yang_data *data)
{
- struct lyd_node *dnode, *dep_dnode;
+ struct lyd_node *dnode, *dep_dnode, *old_dnode, *parent;
char xpath_edit[XPATH_MAXLEN];
char dep_xpath[XPATH_MAXLEN];
uint32_t options = 0;
@@ -754,6 +754,41 @@ int nb_candidate_edit(struct nb_config *candidate,
}
lyd_free_tree(dnode);
break;
+ case NB_OP_REPLACE:
+ old_dnode = yang_dnode_get(candidate->dnode, xpath_edit);
+ if (old_dnode) {
+ parent = lyd_parent(old_dnode);
+ lyd_unlink_tree(old_dnode);
+ }
+ err = dnode_create(candidate, xpath_edit, data->value, options,
+ &dnode);
+ if (!err && dnode && !old_dnode) {
+ /* create dependency if the node didn't exist */
+ nb_node = dnode->schema->priv;
+ if (nb_node->dep_cbs.get_dependency_xpath) {
+ nb_node->dep_cbs.get_dependency_xpath(
+ dnode, dep_xpath);
+
+ err = dnode_create(candidate, dep_xpath, NULL,
+ LYD_NEW_PATH_UPDATE, NULL);
+ if (err)
+ lyd_free_tree(dnode);
+ }
+ }
+ if (old_dnode) {
+ /* restore original node on error, free it otherwise */
+ if (err) {
+ if (parent)
+ lyd_insert_child(parent, old_dnode);
+ else
+ lyd_insert_sibling(candidate->dnode,
+ old_dnode, NULL);
+ return err;
+ }
+
+ lyd_free_tree(old_dnode);
+ }
+ break;
case NB_OP_MOVE:
/* TODO: update configuration. */
break;
@@ -775,6 +810,8 @@ const char *nb_operation_name(enum nb_operation operation)
return "destroy";
case NB_OP_DELETE:
return "delete";
+ case NB_OP_REPLACE:
+ return "replace";
case NB_OP_MOVE:
return "move";
}
@@ -786,7 +823,7 @@ bool nb_is_operation_allowed(struct nb_node *nb_node, enum nb_operation oper)
{
if (lysc_is_key(nb_node->snode)) {
if (oper == NB_OP_MODIFY || oper == NB_OP_DESTROY
- || oper == NB_OP_DELETE)
+ || oper == NB_OP_DELETE || oper == NB_OP_REPLACE)
return false;
}
return true;
diff --git a/lib/northbound.h b/lib/northbound.h
index ef774fb476..3dd9d09d4a 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -723,6 +723,7 @@ enum nb_operation {
NB_OP_MODIFY,
NB_OP_DESTROY,
NB_OP_DELETE,
+ NB_OP_REPLACE,
NB_OP_MOVE,
};
diff --git a/lib/vty.c b/lib/vty.c
index 7e856e3741..5f9f0dc243 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -4011,6 +4011,11 @@ int vty_mgmt_send_config_data(struct vty *vty, const char *xpath_base,
MGMTD__CFG_DATA_REQ_TYPE__CREATE_DATA;
break;
+ case NB_OP_REPLACE:
+ cfg_req[indx].req_type =
+ MGMTD__CFG_DATA_REQ_TYPE__REPLACE_DATA;
+ break;
+
case NB_OP_CREATE:
case NB_OP_MODIFY:
case NB_OP_MOVE:
diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c
index dee75e6586..76681e3076 100644
--- a/mgmtd/mgmt_txn.c
+++ b/mgmtd/mgmt_txn.c
@@ -2072,6 +2072,9 @@ int mgmt_txn_send_set_config_req(uint64_t txn_id, uint64_t req_id,
case MGMTD__CFG_DATA_REQ_TYPE__CREATE_DATA:
cfg_chg->operation = NB_OP_CREATE_EXCL;
break;
+ case MGMTD__CFG_DATA_REQ_TYPE__REPLACE_DATA:
+ cfg_chg->operation = NB_OP_REPLACE;
+ break;
case MGMTD__CFG_DATA_REQ_TYPE__REQ_TYPE_NONE:
case _MGMTD__CFG_DATA_REQ_TYPE_IS_INT_SIZE:
default:
diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c
index b12f54ccbe..2591930e4a 100644
--- a/mgmtd/mgmt_vty.c
+++ b/mgmtd/mgmt_vty.c
@@ -212,6 +212,24 @@ DEFPY(mgmt_remove_config_data, mgmt_remove_config_data_cmd,
return CMD_SUCCESS;
}
+DEFPY(mgmt_replace_config_data, mgmt_replace_config_data_cmd,
+ "mgmt replace-config WORD$path VALUE",
+ MGMTD_STR
+ "Replace configuration data\n"
+ "XPath expression specifying the YANG data path\n"
+ "Value of the data to set\n")
+{
+
+ strlcpy(vty->cfg_changes[0].xpath, path,
+ sizeof(vty->cfg_changes[0].xpath));
+ vty->cfg_changes[0].value = value;
+ vty->cfg_changes[0].operation = NB_OP_REPLACE;
+ vty->num_cfg_changes = 1;
+
+ vty_mgmt_send_config_data(vty, NULL, false);
+ return CMD_SUCCESS;
+}
+
DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd,
"show mgmt get-config [candidate|operational|running]$dsname WORD$path",
SHOW_STR MGMTD_STR
@@ -565,6 +583,7 @@ void mgmt_vty_init(void)
install_element(CONFIG_NODE, &mgmt_set_config_data_cmd);
install_element(CONFIG_NODE, &mgmt_delete_config_data_cmd);
install_element(CONFIG_NODE, &mgmt_remove_config_data_cmd);
+ install_element(CONFIG_NODE, &mgmt_replace_config_data_cmd);
install_element(CONFIG_NODE, &mgmt_load_config_cmd);
install_element(CONFIG_NODE, &mgmt_save_config_cmd);
install_element(CONFIG_NODE, &mgmt_rollback_cmd);