mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 06:55:18 +00:00
mgmtd: add ability to choose datastore to get data from
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
parent
4317c8ffa6
commit
e13c590abe
@ -310,8 +310,8 @@ int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
|
||||
*/
|
||||
int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
|
||||
uint64_t session_id, uint64_t req_id,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint8_t defaults, const char *xpath)
|
||||
uint8_t datastore, LYD_FORMAT result_type,
|
||||
uint8_t flags, uint8_t defaults, const char *xpath)
|
||||
{
|
||||
struct mgmt_msg_get_data *msg;
|
||||
size_t xplen = strlen(xpath);
|
||||
@ -325,6 +325,7 @@ int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
|
||||
msg->result_type = result_type;
|
||||
msg->flags = flags;
|
||||
msg->defaults = defaults;
|
||||
msg->datastore = datastore;
|
||||
strlcpy(msg->xpath, xpath, xplen + 1);
|
||||
|
||||
MGMTD_FE_CLIENT_DBG("Sending GET_DATA_REQ session-id %" PRIu64
|
||||
|
@ -384,6 +384,9 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
|
||||
* req_id
|
||||
* Client request ID.
|
||||
*
|
||||
* datastore
|
||||
* Datastore for getting data.
|
||||
*
|
||||
* result_type
|
||||
* The LYD_FORMAT of the result.
|
||||
*
|
||||
@ -401,8 +404,9 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
|
||||
*/
|
||||
extern int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
|
||||
uint64_t session_id, uint64_t req_id,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint8_t defaults, const char *xpath);
|
||||
uint8_t datastore, LYD_FORMAT result_type,
|
||||
uint8_t flags, uint8_t defaults,
|
||||
const char *xpath);
|
||||
|
||||
/*
|
||||
* Destroy library and cleanup everything.
|
||||
|
@ -154,6 +154,14 @@ DECLARE_MTYPE(MSG_NATIVE_NOTIFY);
|
||||
#define MGMT_MSG_CODE_GET_DATA 3
|
||||
#define MGMT_MSG_CODE_NOTIFY 4
|
||||
|
||||
/*
|
||||
* Datastores
|
||||
*/
|
||||
#define MGMT_MSG_DATASTORE_STARTUP 0
|
||||
#define MGMT_MSG_DATASTORE_CANDIDATE 1
|
||||
#define MGMT_MSG_DATASTORE_RUNNING 2
|
||||
#define MGMT_MSG_DATASTORE_OPERATIONAL 3
|
||||
|
||||
/**
|
||||
* struct mgmt_msg_header - Header common to all native messages.
|
||||
*
|
||||
@ -262,7 +270,8 @@ struct mgmt_msg_get_data {
|
||||
uint8_t result_type;
|
||||
uint8_t flags;
|
||||
uint8_t defaults;
|
||||
uint8_t resv2[6];
|
||||
uint8_t datastore;
|
||||
uint8_t resv2[4];
|
||||
|
||||
alignas(8) char xpath[];
|
||||
};
|
||||
|
10
lib/vty.c
10
lib/vty.c
@ -4101,17 +4101,17 @@ int vty_mgmt_send_get_req(struct vty *vty, bool is_config,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type,
|
||||
uint8_t flags, uint8_t defaults,
|
||||
const char *xpath)
|
||||
int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint8_t defaults, const char *xpath)
|
||||
{
|
||||
LYD_FORMAT intern_format = result_type;
|
||||
|
||||
vty->mgmt_req_id++;
|
||||
|
||||
if (mgmt_fe_send_get_data_req(mgmt_fe_client, vty->mgmt_session_id,
|
||||
vty->mgmt_req_id, intern_format, flags,
|
||||
defaults, xpath)) {
|
||||
vty->mgmt_req_id, datastore,
|
||||
intern_format, flags, defaults, xpath)) {
|
||||
zlog_err("Failed to send GET-DATA to MGMTD session-id: %" PRIu64
|
||||
" req-id %" PRIu64 ".",
|
||||
vty->mgmt_session_id, vty->mgmt_req_id);
|
||||
|
@ -420,9 +420,9 @@ extern int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only,
|
||||
extern int vty_mgmt_send_get_req(struct vty *vty, bool is_config,
|
||||
Mgmtd__DatastoreId datastore,
|
||||
const char **xpath_list, int num_req);
|
||||
extern int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type,
|
||||
uint8_t flags, uint8_t defaults,
|
||||
const char *xpath);
|
||||
extern int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint8_t defaults, const char *xpath);
|
||||
extern int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id,
|
||||
bool lock, bool scok);
|
||||
extern void vty_mgmt_resume_response(struct vty *vty, int ret);
|
||||
|
@ -1145,6 +1145,7 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
|
||||
struct lysc_node **snodes = NULL;
|
||||
char *xpath_resolved = NULL;
|
||||
uint64_t req_id = msg->req_id;
|
||||
Mgmtd__DatastoreId ds_id;
|
||||
uint64_t clients;
|
||||
uint32_t wd_options;
|
||||
bool simple_xpath;
|
||||
@ -1191,6 +1192,24 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (msg->datastore) {
|
||||
case MGMT_MSG_DATASTORE_CANDIDATE:
|
||||
ds_id = MGMTD_DS_CANDIDATE;
|
||||
break;
|
||||
case MGMT_MSG_DATASTORE_RUNNING:
|
||||
ds_id = MGMTD_DS_RUNNING;
|
||||
break;
|
||||
case MGMT_MSG_DATASTORE_OPERATIONAL:
|
||||
ds_id = MGMTD_DS_OPERATIONAL;
|
||||
break;
|
||||
default:
|
||||
fe_adapter_send_error(session, req_id, false, -EINVAL,
|
||||
"Unsupported datastore %" PRIu8
|
||||
" requested from session-id: %" PRIu64,
|
||||
msg->datastore, session->session_id);
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = yang_resolve_snode_xpath(ly_native_ctx, msg->xpath, &snodes,
|
||||
&simple_xpath);
|
||||
if (err) {
|
||||
@ -1228,7 +1247,7 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
|
||||
|
||||
/* Create a GET-TREE request under the transaction */
|
||||
ret = mgmt_txn_send_get_tree_oper(session->txn_id, req_id, clients,
|
||||
msg->result_type, msg->flags,
|
||||
ds_id, msg->result_type, msg->flags,
|
||||
wd_options, simple_xpath, msg->xpath);
|
||||
if (ret) {
|
||||
/* destroy the just created txn */
|
||||
|
@ -2341,9 +2341,10 @@ int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
|
||||
* has registered operational state that matches the given `xpath`
|
||||
*/
|
||||
int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
uint64_t clients, LYD_FORMAT result_type,
|
||||
uint8_t flags, uint32_t wd_options,
|
||||
bool simple_xpath, const char *xpath)
|
||||
uint64_t clients, Mgmtd__DatastoreId ds_id,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint32_t wd_options, bool simple_xpath,
|
||||
const char *xpath)
|
||||
{
|
||||
struct mgmt_msg_get_tree *msg;
|
||||
struct mgmt_txn_ctx *txn;
|
||||
@ -2367,8 +2368,14 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
get_tree->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath);
|
||||
|
||||
if (CHECK_FLAG(flags, GET_DATA_FLAG_CONFIG)) {
|
||||
/*
|
||||
* If the requested datastore is operational, get the config
|
||||
* from running.
|
||||
*/
|
||||
struct mgmt_ds_ctx *ds =
|
||||
mgmt_ds_get_ctx_by_id(mm, MGMTD_DS_RUNNING);
|
||||
mgmt_ds_get_ctx_by_id(mm, ds_id == MGMTD_DS_OPERATIONAL
|
||||
? MGMTD_DS_RUNNING
|
||||
: ds_id);
|
||||
struct nb_config *config = mgmt_ds_get_nb_config(ds);
|
||||
|
||||
if (config) {
|
||||
@ -2414,7 +2421,8 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
}
|
||||
state:
|
||||
/* If we are only getting config, we are done */
|
||||
if (!CHECK_FLAG(flags, GET_DATA_FLAG_STATE) || !clients)
|
||||
if (!CHECK_FLAG(flags, GET_DATA_FLAG_STATE) ||
|
||||
ds_id != MGMTD_DS_OPERATIONAL || !clients)
|
||||
return txn_get_tree_data_done(txn, txn_req);
|
||||
|
||||
msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_get_tree, slen + 1,
|
||||
|
@ -202,6 +202,7 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
|
||||
* txn_id: Transaction identifier.
|
||||
* req_id: FE client request identifier.
|
||||
* clients: Bitmask of clients to send get-tree to.
|
||||
* ds_id: datastore ID.
|
||||
* result_type: LYD_FORMAT result format.
|
||||
* flags: option flags for the request.
|
||||
* wd_options: LYD_PRINT_WD_* flags for the result.
|
||||
@ -212,9 +213,11 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
|
||||
* 0 on success.
|
||||
*/
|
||||
extern int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
uint64_t clients, LYD_FORMAT result_type,
|
||||
uint8_t flags, uint32_t wd_options,
|
||||
bool simple_xpath, const char *xpath);
|
||||
uint64_t clients,
|
||||
Mgmtd__DatastoreId ds_id,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint32_t wd_options, bool simple_xpath,
|
||||
const char *xpath);
|
||||
|
||||
/*
|
||||
* Notifiy backend adapter on connection.
|
||||
|
@ -258,11 +258,15 @@ DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd,
|
||||
}
|
||||
|
||||
DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
"show mgmt get-data WORD$path [with-config|only-config]$content [exact]$exact [with-defaults <trim|all-tag|all>$wd] [json|xml]$fmt",
|
||||
"show mgmt get-data WORD$path [datastore <candidate|running|operational>$ds] [with-config|only-config]$content [exact]$exact [with-defaults <trim|all-tag|all>$wd] [json|xml]$fmt",
|
||||
SHOW_STR
|
||||
MGMTD_STR
|
||||
"Get a data from the operational datastore\n"
|
||||
"XPath expression specifying the YANG data root\n"
|
||||
"Specify datastore to get data from (operational by default)\n"
|
||||
"Candidate datastore\n"
|
||||
"Running datastore\n"
|
||||
"Operational datastore\n"
|
||||
"Include \"config true\" data\n"
|
||||
"Get only \"config true\" data\n"
|
||||
"Get exact node instead of the whole data tree\n"
|
||||
@ -278,6 +282,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
char *xpath = NULL;
|
||||
uint8_t flags = content ? GET_DATA_FLAG_CONFIG : GET_DATA_FLAG_STATE;
|
||||
uint8_t defaults = GET_DATA_DEFAULTS_EXPLICIT;
|
||||
uint8_t datastore = MGMT_MSG_DATASTORE_OPERATIONAL;
|
||||
|
||||
if (content && content[0] == 'w')
|
||||
flags |= GET_DATA_FLAG_STATE;
|
||||
@ -294,6 +299,13 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
defaults = GET_DATA_DEFAULTS_ALL;
|
||||
}
|
||||
|
||||
if (ds) {
|
||||
if (ds[0] == 'c')
|
||||
datastore = MGMT_MSG_DATASTORE_CANDIDATE;
|
||||
else if (ds[0] == 'r')
|
||||
datastore = MGMT_MSG_DATASTORE_RUNNING;
|
||||
}
|
||||
|
||||
/* get rid of extraneous trailing slash-* or single '/' unless root */
|
||||
if (plen > 2 && ((path[plen - 2] == '/' && path[plen - 1] == '*') ||
|
||||
(path[plen - 2] != '/' && path[plen - 1] == '/'))) {
|
||||
@ -303,7 +315,8 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
path = xpath;
|
||||
}
|
||||
|
||||
vty_mgmt_send_get_data_req(vty, format, flags, defaults, path);
|
||||
vty_mgmt_send_get_data_req(vty, datastore, format, flags, defaults,
|
||||
path);
|
||||
|
||||
if (xpath)
|
||||
XFREE(MTYPE_TMP, xpath);
|
||||
|
Loading…
Reference in New Issue
Block a user