]> git.puffer.fish Git - matthieu/frr.git/commitdiff
mgmtd: add ability to choose datastore to get data from
authorIgor Ryzhov <iryzhov@nfware.com>
Fri, 26 Jan 2024 01:08:55 +0000 (03:08 +0200)
committerIgor Ryzhov <iryzhov@nfware.com>
Wed, 31 Jan 2024 00:20:13 +0000 (02:20 +0200)
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
lib/mgmt_fe_client.c
lib/mgmt_fe_client.h
lib/mgmt_msg_native.h
lib/vty.c
lib/vty.h
mgmtd/mgmt_fe_adapter.c
mgmtd/mgmt_txn.c
mgmtd/mgmt_txn.h
mgmtd/mgmt_vty.c

index 19fbdaf1bdc70cfb3bdddfce54bf2198ede67e78..c841821117df1cc208bd03eb5c16955430e40b59 100644 (file)
@@ -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
index 17ec354a1ad3dcc78d3ba35efeabb45beb432070..50ebb801490effd457156ffcda60c55ef87499e2 100644 (file)
@@ -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.
index b26f07a643c4c6d99f8116b209a1f3b6762df514..ab305b125bd9758db411433e7d306fa1cfede657 100644 (file)
@@ -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[];
 };
index c082c8385c86bb92403ee562a6c3b67670ca41b0..c993358e5a066e7fb2672ce6844a8216e6324f91 100644 (file)
--- a/lib/vty.c
+++ b/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);
index 7244aeceed1d759b1e3306adce7030a3be701499..06973da9161fce3557d0514f5b29a7943c215753 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -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);
index acf77f552b7369ca842a1df9f7831794b98ff4d2..5dd6a7001256212c867e7a12e308f6e1a046e17c 100644 (file)
@@ -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 */
index 926b1574a14f68400aebef31ae3eebe4cf01f886..dd2023a4fb17231ca79719593b8c58047da46d6a 100644 (file)
@@ -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,
index ad2e38fb0fed5885412f621d8043b4224eeccf99..b7198326da7e0b99a9bcb8e56e7289cc5c2c2690 100644 (file)
@@ -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.
index 7c9c3c6fe024c3a8baccd3284e1b1e2422c75914..12ea62eceff541e46496572cf6c8ef03ce365d74 100644 (file)
@@ -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);