1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2021 Vmware, Inc.
6 * Pushpasis Sarkar <spushpasis@vmware.com>
13 #include "northbound_cli.h"
15 #include "mgmtd/mgmt.h"
16 #include "mgmtd/mgmt_be_server.h"
17 #include "mgmtd/mgmt_be_adapter.h"
18 #include "mgmtd/mgmt_fe_server.h"
19 #include "mgmtd/mgmt_fe_adapter.h"
20 #include "mgmtd/mgmt_ds.h"
21 #include "mgmtd/mgmt_history.h"
23 #include "mgmtd/mgmt_vty_clippy.c"
25 DEFPY(show_mgmt_be_adapter
,
26 show_mgmt_be_adapter_cmd
,
27 "show mgmt backend-adapter all",
31 "Display all Backend Adapters\n")
33 mgmt_be_adapter_status_write(vty
);
38 DEFPY(show_mgmt_be_xpath_reg
,
39 show_mgmt_be_xpath_reg_cmd
,
40 "show mgmt backend-yang-xpath-registry",
43 "Backend Adapter YANG Xpath Registry\n")
45 mgmt_be_xpath_register_write(vty
);
50 DEFPY(show_mgmt_fe_adapter
, show_mgmt_fe_adapter_cmd
,
51 "show mgmt frontend-adapter all [detail$detail]",
55 "Display all Frontend Adapters\n"
56 "Display more details\n")
58 mgmt_fe_adapter_status_write(vty
, !!detail
);
63 DEFPY_HIDDEN(mgmt_performance_measurement
,
64 mgmt_performance_measurement_cmd
,
65 "[no] mgmt performance-measurement",
68 "Enable performance measurement\n")
71 mgmt_fe_adapter_perf_measurement(vty
, false);
73 mgmt_fe_adapter_perf_measurement(vty
, true);
78 DEFPY(mgmt_reset_performance_stats
,
79 mgmt_reset_performance_stats_cmd
,
80 "mgmt reset-statistics",
82 "Reset the Performance measurement statistics\n")
84 mgmt_fe_adapter_reset_perf_stats(vty
);
91 "show mgmt transaction all",
95 "Display all Transactions\n")
97 mgmt_txn_status_write(vty
);
104 "show mgmt datastore [all|candidate|operational|running]$dsname",
108 "All datastores (default)\n"
109 "Candidate datastore\n"
110 "Operational datastore\n"
111 "Running datastore\n")
113 struct mgmt_ds_ctx
*ds_ctx
;
115 if (!dsname
|| dsname
[0] == 'a') {
116 mgmt_ds_status_write(vty
);
119 ds_ctx
= mgmt_ds_get_ctx_by_id(mm
, mgmt_ds_name2id(dsname
));
121 vty_out(vty
, "ERROR: Could not access %s datastore!\n", dsname
);
122 return CMD_ERR_NO_MATCH
;
124 mgmt_ds_status_write_one(vty
, ds_ctx
);
131 "mgmt commit <check|apply|abort>$type",
134 "Validate the set of config commands\n"
135 "Validate and apply the set of config commands\n"
136 "Abort and drop the set of config commands recently added\n")
138 bool validate_only
= type
[0] == 'c';
139 bool abort
= type
[1] == 'b';
141 if (vty_mgmt_send_commit_config(vty
, validate_only
, abort
) != 0)
142 return CMD_WARNING_CONFIG_FAILED
;
146 DEFPY(mgmt_set_config_data
, mgmt_set_config_data_cmd
,
147 "mgmt set-config WORD$path VALUE",
149 "Set configuration data\n"
150 "XPath expression specifying the YANG data path\n"
151 "Value of the data to set\n")
153 strlcpy(vty
->cfg_changes
[0].xpath
, path
,
154 sizeof(vty
->cfg_changes
[0].xpath
));
155 vty
->cfg_changes
[0].value
= value
;
156 vty
->cfg_changes
[0].operation
= NB_OP_CREATE
;
157 vty
->num_cfg_changes
= 1;
159 vty
->no_implicit_commit
= true;
160 vty_mgmt_send_config_data(vty
);
161 vty
->no_implicit_commit
= false;
165 DEFPY(mgmt_delete_config_data
, mgmt_delete_config_data_cmd
,
166 "mgmt delete-config WORD$path",
168 "Delete configuration data\n"
169 "XPath expression specifying the YANG data path\n")
172 strlcpy(vty
->cfg_changes
[0].xpath
, path
,
173 sizeof(vty
->cfg_changes
[0].xpath
));
174 vty
->cfg_changes
[0].value
= NULL
;
175 vty
->cfg_changes
[0].operation
= NB_OP_DESTROY
;
176 vty
->num_cfg_changes
= 1;
178 vty
->no_implicit_commit
= true;
179 vty_mgmt_send_config_data(vty
);
180 vty
->no_implicit_commit
= false;
184 DEFPY(show_mgmt_get_config
, show_mgmt_get_config_cmd
,
185 "show mgmt get-config [candidate|operational|running]$dsname WORD$path",
187 "Get configuration data from a specific configuration datastore\n"
188 "Candidate datastore (default)\n"
189 "Operational datastore\n"
190 "Running datastore\n"
191 "XPath expression specifying the YANG data path\n")
193 const char *xpath_list
[VTY_MAXCFGCHANGES
] = {0};
194 Mgmtd__DatastoreId datastore
= MGMTD_DS_CANDIDATE
;
197 datastore
= mgmt_ds_name2id(dsname
);
199 xpath_list
[0] = path
;
200 vty_mgmt_send_get_config(vty
, datastore
, xpath_list
, 1);
204 DEFPY(show_mgmt_get_data
, show_mgmt_get_data_cmd
,
205 "show mgmt get-data [candidate|operational|running]$dsname WORD$path",
207 "Get data from a specific datastore\n"
208 "Candidate datastore\n"
209 "Operational datastore (default)\n"
210 "Running datastore\n"
211 "XPath expression specifying the YANG data path\n")
213 const char *xpath_list
[VTY_MAXCFGCHANGES
] = {0};
214 Mgmtd__DatastoreId datastore
= MGMTD_DS_OPERATIONAL
;
217 datastore
= mgmt_ds_name2id(dsname
);
219 xpath_list
[0] = path
;
220 vty_mgmt_send_get_data(vty
, datastore
, xpath_list
, 1);
224 DEFPY(show_mgmt_dump_data
,
225 show_mgmt_dump_data_cmd
,
226 "show mgmt datastore-contents [candidate|operational|running]$dsname [xpath WORD$path] [file WORD$filepath] <json|xml>$fmt",
229 "Get Datastore contents from a specific datastore\n"
230 "Candidate datastore (default)\n"
231 "Operational datastore\n"
232 "Running datastore\n"
233 "XPath expression specifying the YANG data path\n"
235 "Dump the contents to a file\n"
236 "Full path of the file\n"
240 struct mgmt_ds_ctx
*ds_ctx
;
241 Mgmtd__DatastoreId datastore
= MGMTD_DS_CANDIDATE
;
242 LYD_FORMAT format
= fmt
[0] == 'j' ? LYD_JSON
: LYD_XML
;
246 datastore
= mgmt_ds_name2id(dsname
);
248 ds_ctx
= mgmt_ds_get_ctx_by_id(mm
, datastore
);
250 vty_out(vty
, "ERROR: Could not access datastore!\n");
251 return CMD_ERR_NO_MATCH
;
255 f
= fopen(filepath
, "w");
258 "Could not open file pointed by filepath %s\n",
264 mgmt_ds_dump_tree(vty
, ds_ctx
, path
, f
, format
);
271 DEFPY(show_mgmt_map_xpath
,
272 show_mgmt_map_xpath_cmd
,
273 "show mgmt yang-xpath-subscription WORD$path",
276 "Get YANG Backend Subscription\n"
277 "XPath expression specifying the YANG data path\n")
279 mgmt_be_xpath_subscr_info_write(vty
, path
);
283 DEFPY(mgmt_load_config
,
284 mgmt_load_config_cmd
,
285 "mgmt load-config WORD$filepath <merge|replace>$type",
287 "Load configuration onto Candidate Datastore\n"
288 "Full path of the file\n"
289 "Merge configuration with contents of Candidate Datastore\n"
290 "Replace the existing contents of Candidate datastore\n")
292 bool merge
= type
[0] == 'm' ? true : false;
293 struct mgmt_ds_ctx
*ds_ctx
;
296 if (access(filepath
, F_OK
) == -1) {
297 vty_out(vty
, "ERROR: File %s : %s\n", filepath
,
299 return CMD_ERR_NO_FILE
;
302 ds_ctx
= mgmt_ds_get_ctx_by_id(mm
, MGMTD_DS_CANDIDATE
);
304 vty_out(vty
, "ERROR: Could not access Candidate datastore!\n");
305 return CMD_ERR_NO_MATCH
;
308 ret
= mgmt_ds_load_config_from_file(ds_ctx
, filepath
, merge
);
310 vty_out(vty
, "Error with parsing the file with error code %d\n",
315 DEFPY(mgmt_save_config
,
316 mgmt_save_config_cmd
,
317 "mgmt save-config <candidate|running>$dsname WORD$filepath",
319 "Save configuration from datastore\n"
320 "Candidate datastore\n"
321 "Running datastore\n"
322 "Full path of the file\n")
324 Mgmtd__DatastoreId datastore
= mgmt_ds_name2id(dsname
);
325 struct mgmt_ds_ctx
*ds_ctx
;
328 ds_ctx
= mgmt_ds_get_ctx_by_id(mm
, datastore
);
330 vty_out(vty
, "ERROR: Could not access the '%s' datastore!\n",
332 return CMD_ERR_NO_MATCH
;
336 vty_out(vty
, "ERROR: No file path mentioned!\n");
337 return CMD_ERR_NO_MATCH
;
340 f
= fopen(filepath
, "w");
342 vty_out(vty
, "Could not open file pointed by filepath %s\n",
347 mgmt_ds_dump_tree(vty
, ds_ctx
, "/", f
, LYD_JSON
);
354 DEFPY(show_mgmt_cmt_hist
,
355 show_mgmt_cmt_hist_cmd
,
356 "show mgmt commit-history",
359 "Show commit history\n")
361 show_mgmt_cmt_history(vty
);
367 "mgmt rollback <commit-id WORD$commit | last [(1-10)]$last>",
370 "Rollback to commit ID\n"
372 "Rollbak n commits\n"
373 "Number of commits\n")
376 mgmt_history_rollback_by_id(vty
, commit
);
378 mgmt_history_rollback_n(vty
, last
);
383 int config_write_mgmt_debug(struct vty
*vty
);
384 static struct cmd_node debug_node
= {
388 .config_write
= config_write_mgmt_debug
,
391 static int write_mgmt_debug_helper(struct vty
*vty
, bool config
)
393 uint32_t mode
= config
? DEBUG_MODE_CONF
: DEBUG_MODE_ALL
;
394 bool be
= DEBUG_MODE_CHECK(&mgmt_debug_be
, mode
);
395 bool ds
= DEBUG_MODE_CHECK(&mgmt_debug_ds
, mode
);
396 bool fe
= DEBUG_MODE_CHECK(&mgmt_debug_fe
, mode
);
397 bool txn
= DEBUG_MODE_CHECK(&mgmt_debug_txn
, mode
);
399 if (!(be
|| ds
|| fe
|| txn
))
402 vty_out(vty
, "debug mgmt");
404 vty_out(vty
, " backend");
406 vty_out(vty
, " datastore");
408 vty_out(vty
, " frontend");
410 vty_out(vty
, " transaction");
417 int config_write_mgmt_debug(struct vty
*vty
)
419 return write_mgmt_debug_helper(vty
, true);
422 DEFPY_NOSH(show_debugging_mgmt
, show_debugging_mgmt_cmd
,
423 "show debugging [mgmt]", SHOW_STR DEBUG_STR
"MGMT Information\n")
425 vty_out(vty
, "MGMT debugging status:\n");
427 write_mgmt_debug_helper(vty
, false);
429 cmd_show_lib_debugs(vty
);
434 DEFPY(debug_mgmt
, debug_mgmt_cmd
,
435 "[no$no] debug mgmt {backend$be|datastore$ds|frontend$fe|transaction$txn}",
436 NO_STR DEBUG_STR MGMTD_STR
440 "Transaction debug\n")
442 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
445 DEBUG_MODE_SET(&mgmt_debug_be
, mode
, !no
);
447 DEBUG_MODE_SET(&mgmt_debug_ds
, mode
, !no
);
449 DEBUG_MODE_SET(&mgmt_debug_fe
, mode
, !no
);
451 DEBUG_MODE_SET(&mgmt_debug_txn
, mode
, !no
);
457 * Analog of `frr_config_read_in()`, instead of our config file though we loop
458 * over all daemons that have transitioned to mgmtd, loading their configs
460 static int mgmt_config_pre_hook(struct event_loop
*loop
)
465 for (uint i
= 0; i
< mgmt_daemons_count
; i
++) {
466 p
= asprintfrr(MTYPE_TMP
, "%s/%s.conf", frr_sysconfdir
,
468 confp
= fopen(p
, "r");
471 zlog_err("%s: couldn't read config file %s: %s",
472 __func__
, p
, safe_strerror(errno
));
474 zlog_info("mgmtd: reading daemon config from %s", p
);
475 vty_read_file(vty_shared_candidate_config
, confp
);
483 void mgmt_vty_init(void)
486 * Initialize command handling from VTYSH connection.
487 * Call command initialization routines defined by
488 * backend components that are moved to new MGMTD infra
492 extern void static_vty_init(void);
496 hook_register(frr_config_pre
, mgmt_config_pre_hook
);
498 install_node(&debug_node
);
500 install_element(VIEW_NODE
, &show_mgmt_be_adapter_cmd
);
501 install_element(VIEW_NODE
, &show_mgmt_be_xpath_reg_cmd
);
502 install_element(VIEW_NODE
, &show_mgmt_fe_adapter_cmd
);
503 install_element(VIEW_NODE
, &show_mgmt_txn_cmd
);
504 install_element(VIEW_NODE
, &show_mgmt_ds_cmd
);
505 install_element(VIEW_NODE
, &show_mgmt_get_config_cmd
);
506 install_element(VIEW_NODE
, &show_mgmt_get_data_cmd
);
507 install_element(VIEW_NODE
, &show_mgmt_dump_data_cmd
);
508 install_element(VIEW_NODE
, &show_mgmt_map_xpath_cmd
);
509 install_element(VIEW_NODE
, &show_mgmt_cmt_hist_cmd
);
511 install_element(CONFIG_NODE
, &mgmt_commit_cmd
);
512 install_element(CONFIG_NODE
, &mgmt_set_config_data_cmd
);
513 install_element(CONFIG_NODE
, &mgmt_delete_config_data_cmd
);
514 install_element(CONFIG_NODE
, &mgmt_load_config_cmd
);
515 install_element(CONFIG_NODE
, &mgmt_save_config_cmd
);
516 install_element(CONFIG_NODE
, &mgmt_rollback_cmd
);
518 install_element(VIEW_NODE
, &debug_mgmt_cmd
);
519 install_element(CONFIG_NODE
, &debug_mgmt_cmd
);
522 install_element(ENABLE_NODE
, &mgmt_performance_measurement_cmd
);
523 install_element(ENABLE_NODE
, &mgmt_reset_performance_stats_cmd
);
525 install_element(ENABLE_NODE
, &show_debugging_mgmt_cmd
);
527 mgmt_fe_client_lib_vty_init();
529 * TODO: Register and handlers for auto-completion here.