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 static 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 config_write_mgmt_debug_helper(struct vty
*vty
, bool config
)
393 int n
= mgmt_debug_be
+ mgmt_debug_fe
+ mgmt_debug_ds
+ mgmt_debug_txn
;
398 if (config
&& mgmt_debug_be
&& mgmt_debug_fe
&& mgmt_debug_ds
&&
400 vty_out(vty
, "debug mgmt all\n");
404 vty_out(vty
, "debug mgmt");
406 vty_out(vty
, " backend");
408 vty_out(vty
, " datastore");
410 vty_out(vty
, " frontend");
412 vty_out(vty
, " transaction");
419 static int config_write_mgmt_debug(struct vty
*vty
)
421 return config_write_mgmt_debug_helper(vty
, true);
424 DEFUN_NOSH(show_debugging_mgmt
, show_debugging_mgmt_cmd
,
425 "show debugging [mgmt]", SHOW_STR DEBUG_STR
"MGMT Information\n")
427 vty_out(vty
, "MGMT debugging status:\n");
429 config_write_mgmt_debug_helper(vty
, false);
431 cmd_show_lib_debugs(vty
);
436 DEFPY(debug_mgmt
, debug_mgmt_cmd
,
437 "[no$no] debug mgmt <all$all|{backend$be|datastore$ds|frontend$fe|transaction$txn}>",
438 NO_STR DEBUG_STR MGMTD_STR
443 "Transaction debug\n")
448 be
= fe
= ds
= txn
= set
? all
: NULL
;
457 mgmt_debug_txn
= set
;
463 * Analog of `frr_config_read_in()`, instead of our config file though we loop
464 * over all daemons that have transitioned to mgmtd, loading their configs
466 static int mgmt_config_pre_hook(struct event_loop
*loop
)
471 for (uint i
= 0; i
< mgmt_daemons_count
; i
++) {
472 p
= asprintfrr(MTYPE_TMP
, "%s/%s.conf", frr_sysconfdir
,
474 confp
= fopen(p
, "r");
477 zlog_err("%s: couldn't read config file %s: %s",
478 __func__
, p
, safe_strerror(errno
));
480 zlog_info("mgmtd: reading daemon config from %s", p
);
481 vty_read_file(vty_shared_candidate_config
, confp
);
489 void mgmt_vty_init(void)
492 * Initialize command handling from VTYSH connection.
493 * Call command initialization routines defined by
494 * backend components that are moved to new MGMTD infra
498 extern void static_vty_init(void);
502 hook_register(frr_config_pre
, mgmt_config_pre_hook
);
504 install_node(&debug_node
);
506 install_element(VIEW_NODE
, &show_mgmt_be_adapter_cmd
);
507 install_element(VIEW_NODE
, &show_mgmt_be_xpath_reg_cmd
);
508 install_element(VIEW_NODE
, &show_mgmt_fe_adapter_cmd
);
509 install_element(VIEW_NODE
, &show_mgmt_txn_cmd
);
510 install_element(VIEW_NODE
, &show_mgmt_ds_cmd
);
511 install_element(VIEW_NODE
, &show_mgmt_get_config_cmd
);
512 install_element(VIEW_NODE
, &show_mgmt_get_data_cmd
);
513 install_element(VIEW_NODE
, &show_mgmt_dump_data_cmd
);
514 install_element(VIEW_NODE
, &show_mgmt_map_xpath_cmd
);
515 install_element(VIEW_NODE
, &show_mgmt_cmt_hist_cmd
);
517 install_element(CONFIG_NODE
, &mgmt_commit_cmd
);
518 install_element(CONFIG_NODE
, &mgmt_set_config_data_cmd
);
519 install_element(CONFIG_NODE
, &mgmt_delete_config_data_cmd
);
520 install_element(CONFIG_NODE
, &mgmt_load_config_cmd
);
521 install_element(CONFIG_NODE
, &mgmt_save_config_cmd
);
522 install_element(CONFIG_NODE
, &mgmt_rollback_cmd
);
524 install_element(VIEW_NODE
, &debug_mgmt_cmd
);
525 install_element(CONFIG_NODE
, &debug_mgmt_cmd
);
528 install_element(ENABLE_NODE
, &mgmt_performance_measurement_cmd
);
529 install_element(ENABLE_NODE
, &mgmt_reset_performance_stats_cmd
);
531 install_element(ENABLE_NODE
, &show_debugging_mgmt_cmd
);
534 * TODO: Register and handlers for auto-completion here.