/*
* Operation to apply (either NB_OP_CREATE, NB_OP_MODIFY or
- * NB_OP_DELETE).
+ * NB_OP_DESTROY).
*/
enum nb_operation operation;
},
{
.xpath = "./access-list",
- .operation = acl ? NB_OP_MODIFY : NB_OP_DELETE,
+ .operation = acl ? NB_OP_MODIFY : NB_OP_DESTROY,
.value = acl,
},
};
struct cli_config_change changes[] = {
{
.xpath = ".",
- .operation = NB_OP_DELETE,
+ .operation = NB_OP_DESTROY,
},
};
enum CfgDataReqType {
REQ_TYPE_NONE = 0;
SET_DATA = 1;
- DELETE_DATA = 2;
+ REMOVE_DATA = 2;
CREATE_DATA = 3;
+ DELETE_DATA = 4;
}
message YangCfgDataReq {
for (index = 0; index < num_req; index++) {
cfg_chg = &txn_req->req.set_cfg.cfg_changes[index];
- if (cfg_req[index]->req_type
- == MGMTD__CFG_DATA_REQ_TYPE__DELETE_DATA)
+ /*
+ * Treat all operations as destroy or modify, because we don't
+ * need additional existence checks on the backend. Everything
+ * is already checked by mgmtd.
+ */
+ switch (cfg_req[index]->req_type) {
+ case MGMTD__CFG_DATA_REQ_TYPE__DELETE_DATA:
+ case MGMTD__CFG_DATA_REQ_TYPE__REMOVE_DATA:
cfg_chg->operation = NB_OP_DESTROY;
- else
+ break;
+ case MGMTD__CFG_DATA_REQ_TYPE__SET_DATA:
+ case MGMTD__CFG_DATA_REQ_TYPE__CREATE_DATA:
cfg_chg->operation = NB_OP_MODIFY;
+ break;
+ case MGMTD__CFG_DATA_REQ_TYPE__REQ_TYPE_NONE:
+ case _MGMTD__CFG_DATA_REQ_TYPE_IS_INT_SIZE:
+ default:
+ continue;
+ }
strlcpy(cfg_chg->xpath, cfg_req[index]->data->xpath,
sizeof(cfg_chg->xpath));
}
break;
case NB_OP_DESTROY:
+ case NB_OP_DELETE:
dnode = yang_dnode_get(candidate->dnode, xpath_edit);
- if (!dnode)
- /*
- * Return a special error code so the caller can choose
- * whether to ignore it or not.
- */
- return NB_ERR_NOT_FOUND;
+ if (!dnode) {
+ if (operation == NB_OP_DELETE)
+ return NB_ERR;
+ else
+ return NB_OK;
+ }
/* destroy dependant */
if (nb_node->dep_cbs.get_dependant_xpath) {
nb_node->dep_cbs.get_dependant_xpath(dnode, dep_xpath);
return "modify";
case NB_OP_DESTROY:
return "destroy";
+ case NB_OP_DELETE:
+ return "delete";
case NB_OP_MOVE:
return "move";
}
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)
+ if (oper == NB_OP_MODIFY || oper == NB_OP_DESTROY
+ || oper == NB_OP_DELETE)
return false;
}
return true;
ret = nb_candidate_edit(candidate_config, nb_node,
change->operation, xpath, NULL, data);
yang_data_free(data);
- if (ret != NB_OK && ret != NB_ERR_NOT_FOUND) {
+ if (ret != NB_OK) {
flog_warn(
EC_LIB_NB_CANDIDATE_EDIT_ERROR,
"%s: failed to edit candidate configuration: operation [%s] xpath [%s]",
NB_OP_CREATE,
NB_OP_MODIFY,
NB_OP_DESTROY,
+ NB_OP_DELETE,
NB_OP_MOVE,
};
*
* Returns:
* - NB_OK on success.
- * - NB_ERR_NOT_FOUND when the element to be deleted was not found.
* - NB_ERR for other errors.
*/
extern int nb_candidate_edit(struct nb_config *candidate,
* XPath (absolute or relative) of the configuration option being edited.
*
* operation
- * Operation to apply (either NB_OP_CREATE, NB_OP_MODIFY or NB_OP_DELETE).
+ * Operation to apply (either NB_OP_CREATE, NB_OP_MODIFY or NB_OP_DESTROY).
*
* value
* New value of the configuration option. Should be NULL for typeless YANG
ret = nb_candidate_edit(candidate, nb_node, nb_op, xpath, NULL, data);
yang_data_free(data);
- if (ret != NB_OK && ret != NB_ERR_NOT_FOUND) {
+ if (ret != NB_OK) {
flog_warn(
EC_LIB_NB_CANDIDATE_EDIT_ERROR,
"%s: failed to edit candidate configuration: operation [%s] xpath [%s]",
mgmt_yang_cfg_data_req_init(&cfg_req[indx]);
cfg_req[indx].data = &cfg_data[indx];
switch (vty->cfg_changes[indx].operation) {
- case NB_OP_DESTROY:
+ case NB_OP_DELETE:
cfg_req[indx].req_type =
MGMTD__CFG_DATA_REQ_TYPE__DELETE_DATA;
break;
+ case NB_OP_DESTROY:
+ cfg_req[indx].req_type =
+ MGMTD__CFG_DATA_REQ_TYPE__REMOVE_DATA;
+ break;
+
case NB_OP_CREATE_EXCL:
cfg_req[indx].req_type =
MGMTD__CFG_DATA_REQ_TYPE__CREATE_DATA;
*/
if (chg->cb.operation == NB_CB_DESTROY)
batch->cfg_data[batch->num_cfg_data].req_type =
- MGMTD__CFG_DATA_REQ_TYPE__DELETE_DATA;
+ MGMTD__CFG_DATA_REQ_TYPE__REMOVE_DATA;
else
batch->cfg_data[batch->num_cfg_data].req_type =
MGMTD__CFG_DATA_REQ_TYPE__SET_DATA;
switch (cfg_req[indx]->req_type) {
case MGMTD__CFG_DATA_REQ_TYPE__DELETE_DATA:
+ cfg_chg->operation = NB_OP_DELETE;
+ break;
+ case MGMTD__CFG_DATA_REQ_TYPE__REMOVE_DATA:
cfg_chg->operation = NB_OP_DESTROY;
break;
case MGMTD__CFG_DATA_REQ_TYPE__SET_DATA:
"XPath expression specifying the YANG data path\n")
{
+ strlcpy(vty->cfg_changes[0].xpath, path,
+ sizeof(vty->cfg_changes[0].xpath));
+ vty->cfg_changes[0].value = NULL;
+ vty->cfg_changes[0].operation = NB_OP_DELETE;
+ vty->num_cfg_changes = 1;
+
+ vty_mgmt_send_config_data(vty, NULL, false);
+ return CMD_SUCCESS;
+}
+
+DEFPY(mgmt_remove_config_data, mgmt_remove_config_data_cmd,
+ "mgmt remove-config WORD$path",
+ MGMTD_STR
+ "Remove configuration data\n"
+ "XPath expression specifying the YANG data path\n")
+{
+
strlcpy(vty->cfg_changes[0].xpath, path,
sizeof(vty->cfg_changes[0].xpath));
vty->cfg_changes[0].value = NULL;
install_element(CONFIG_NODE, &mgmt_create_config_data_cmd);
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_load_config_cmd);
install_element(CONFIG_NODE, &mgmt_save_config_cmd);
install_element(CONFIG_NODE, &mgmt_rollback_cmd);