]> git.proxmox.com Git - mirror_frr.git/blob - mgmtd/mgmt_vty.c
Merge pull request #12969 from opensourcerouting/ospfd-nssa
[mirror_frr.git] / mgmtd / mgmt_vty.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * MGMTD VTY Interface
4 *
5 * Copyright (C) 2021 Vmware, Inc.
6 * Pushpasis Sarkar <spushpasis@vmware.com>
7 */
8
9 #include <zebra.h>
10
11 #include "command.h"
12 #include "json.h"
13 #include "mgmtd/mgmt.h"
14 #include "mgmtd/mgmt_be_server.h"
15 #include "mgmtd/mgmt_be_adapter.h"
16 #include "mgmtd/mgmt_fe_server.h"
17 #include "mgmtd/mgmt_fe_adapter.h"
18 #include "mgmtd/mgmt_ds.h"
19 #include "mgmtd/mgmt_history.h"
20
21 #include "mgmtd/mgmt_vty_clippy.c"
22
23 DEFPY(show_mgmt_be_adapter,
24 show_mgmt_be_adapter_cmd,
25 "show mgmt backend-adapter all",
26 SHOW_STR
27 MGMTD_STR
28 MGMTD_BE_ADAPTER_STR
29 "Display all Backend Adapters\n")
30 {
31 mgmt_be_adapter_status_write(vty);
32
33 return CMD_SUCCESS;
34 }
35
36 DEFPY(show_mgmt_be_xpath_reg,
37 show_mgmt_be_xpath_reg_cmd,
38 "show mgmt backend-yang-xpath-registry",
39 SHOW_STR
40 MGMTD_STR
41 "Backend Adapter YANG Xpath Registry\n")
42 {
43 mgmt_be_xpath_register_write(vty);
44
45 return CMD_SUCCESS;
46 }
47
48 DEFPY(show_mgmt_fe_adapter, show_mgmt_fe_adapter_cmd,
49 "show mgmt frontend-adapter all [detail$detail]",
50 SHOW_STR
51 MGMTD_STR
52 MGMTD_FE_ADAPTER_STR
53 "Display all Frontend Adapters\n"
54 "Display more details\n")
55 {
56 mgmt_fe_adapter_status_write(vty, !!detail);
57
58 return CMD_SUCCESS;
59 }
60
61 DEFPY_HIDDEN(mgmt_performance_measurement,
62 mgmt_performance_measurement_cmd,
63 "[no] mgmt performance-measurement",
64 NO_STR
65 MGMTD_STR
66 "Enable performance measurement\n")
67 {
68 if (no)
69 mgmt_fe_adapter_perf_measurement(vty, false);
70 else
71 mgmt_fe_adapter_perf_measurement(vty, true);
72
73 return CMD_SUCCESS;
74 }
75
76 DEFPY(mgmt_reset_performance_stats,
77 mgmt_reset_performance_stats_cmd,
78 "mgmt reset-statistics",
79 MGMTD_STR
80 "Reset the Performance measurement statistics\n")
81 {
82 mgmt_fe_adapter_reset_perf_stats(vty);
83
84 return CMD_SUCCESS;
85 }
86
87 DEFPY(show_mgmt_txn,
88 show_mgmt_txn_cmd,
89 "show mgmt transaction all",
90 SHOW_STR
91 MGMTD_STR
92 MGMTD_TXN_STR
93 "Display all Transactions\n")
94 {
95 mgmt_txn_status_write(vty);
96
97 return CMD_SUCCESS;
98 }
99
100 DEFPY(show_mgmt_ds,
101 show_mgmt_ds_cmd,
102 "show mgmt datastore [all|candidate|operational|running]$dsname",
103 SHOW_STR
104 MGMTD_STR
105 MGMTD_DS_STR
106 "All datastores (default)\n"
107 "Candidate datastore\n"
108 "Operational datastore\n"
109 "Running datastore\n")
110 {
111 struct mgmt_ds_ctx *ds_ctx;
112
113 if (!dsname || dsname[0] == 'a') {
114 mgmt_ds_status_write(vty);
115 return CMD_SUCCESS;
116 }
117 ds_ctx = mgmt_ds_get_ctx_by_id(mm, mgmt_ds_name2id(dsname));
118 if (!ds_ctx) {
119 vty_out(vty, "ERROR: Could not access %s datastore!\n", dsname);
120 return CMD_ERR_NO_MATCH;
121 }
122 mgmt_ds_status_write_one(vty, ds_ctx);
123
124 return CMD_SUCCESS;
125 }
126
127 DEFPY(mgmt_commit,
128 mgmt_commit_cmd,
129 "mgmt commit <check|apply|abort>$type",
130 MGMTD_STR
131 "Commit action\n"
132 "Validate the set of config commands\n"
133 "Validate and apply the set of config commands\n"
134 "Abort and drop the set of config commands recently added\n")
135 {
136 bool validate_only = type[0] == 'c';
137 bool abort = type[1] == 'b';
138
139 if (vty_mgmt_send_commit_config(vty, validate_only, abort) != 0)
140 return CMD_WARNING_CONFIG_FAILED;
141 return CMD_SUCCESS;
142 }
143
144 DEFPY(mgmt_set_config_data, mgmt_set_config_data_cmd,
145 "mgmt set-config WORD$path VALUE",
146 MGMTD_STR
147 "Set configuration data\n"
148 "XPath expression specifying the YANG data path\n"
149 "Value of the data to set\n")
150 {
151 strlcpy(vty->cfg_changes[0].xpath, path,
152 sizeof(vty->cfg_changes[0].xpath));
153 vty->cfg_changes[0].value = value;
154 vty->cfg_changes[0].operation = NB_OP_CREATE;
155 vty->num_cfg_changes = 1;
156
157 vty->no_implicit_commit = true;
158 vty_mgmt_send_config_data(vty);
159 vty->no_implicit_commit = false;
160 return CMD_SUCCESS;
161 }
162
163 DEFPY(mgmt_delete_config_data, mgmt_delete_config_data_cmd,
164 "mgmt delete-config WORD$path",
165 MGMTD_STR
166 "Delete configuration data\n"
167 "XPath expression specifying the YANG data path\n")
168 {
169
170 strlcpy(vty->cfg_changes[0].xpath, path,
171 sizeof(vty->cfg_changes[0].xpath));
172 vty->cfg_changes[0].value = NULL;
173 vty->cfg_changes[0].operation = NB_OP_DESTROY;
174 vty->num_cfg_changes = 1;
175
176 vty->no_implicit_commit = true;
177 vty_mgmt_send_config_data(vty);
178 vty->no_implicit_commit = false;
179 return CMD_SUCCESS;
180 }
181
182 DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd,
183 "show mgmt get-config [candidate|operational|running]$dsname WORD$path",
184 SHOW_STR MGMTD_STR
185 "Get configuration data from a specific configuration datastore\n"
186 "Candidate datastore (default)\n"
187 "Operational datastore\n"
188 "Running datastore\n"
189 "XPath expression specifying the YANG data path\n")
190 {
191 const char *xpath_list[VTY_MAXCFGCHANGES] = {0};
192 Mgmtd__DatastoreId datastore = MGMTD_DS_CANDIDATE;
193
194 if (dsname)
195 datastore = mgmt_ds_name2id(dsname);
196
197 xpath_list[0] = path;
198 vty_mgmt_send_get_config(vty, datastore, xpath_list, 1);
199 return CMD_SUCCESS;
200 }
201
202 DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
203 "show mgmt get-data [candidate|operational|running]$dsname WORD$path",
204 SHOW_STR MGMTD_STR
205 "Get data from a specific datastore\n"
206 "Candidate datastore\n"
207 "Operational datastore (default)\n"
208 "Running datastore\n"
209 "XPath expression specifying the YANG data path\n")
210 {
211 const char *xpath_list[VTY_MAXCFGCHANGES] = {0};
212 Mgmtd__DatastoreId datastore = MGMTD_DS_OPERATIONAL;
213
214 if (dsname)
215 datastore = mgmt_ds_name2id(dsname);
216
217 xpath_list[0] = path;
218 vty_mgmt_send_get_data(vty, datastore, xpath_list, 1);
219 return CMD_SUCCESS;
220 }
221
222 DEFPY(show_mgmt_dump_data,
223 show_mgmt_dump_data_cmd,
224 "show mgmt datastore-contents [candidate|operational|running]$dsname [xpath WORD$path] [file WORD$filepath] <json|xml>$fmt",
225 SHOW_STR
226 MGMTD_STR
227 "Get Datastore contents from a specific datastore\n"
228 "Candidate datastore (default)\n"
229 "Operational datastore\n"
230 "Running datastore\n"
231 "XPath expression specifying the YANG data path\n"
232 "XPath string\n"
233 "Dump the contents to a file\n"
234 "Full path of the file\n"
235 "json output\n"
236 "xml output\n")
237 {
238 struct mgmt_ds_ctx *ds_ctx;
239 Mgmtd__DatastoreId datastore = MGMTD_DS_CANDIDATE;
240 LYD_FORMAT format = fmt[0] == 'j' ? LYD_JSON : LYD_XML;
241 FILE *f = NULL;
242
243 if (datastore)
244 datastore = mgmt_ds_name2id(dsname);
245
246 ds_ctx = mgmt_ds_get_ctx_by_id(mm, datastore);
247 if (!ds_ctx) {
248 vty_out(vty, "ERROR: Could not access datastore!\n");
249 return CMD_ERR_NO_MATCH;
250 }
251
252 if (filepath) {
253 f = fopen(filepath, "w");
254 if (!f) {
255 vty_out(vty,
256 "Could not open file pointed by filepath %s\n",
257 filepath);
258 return CMD_SUCCESS;
259 }
260 }
261
262 mgmt_ds_dump_tree(vty, ds_ctx, path, f, format);
263
264 if (f)
265 fclose(f);
266 return CMD_SUCCESS;
267 }
268
269 DEFPY(show_mgmt_map_xpath,
270 show_mgmt_map_xpath_cmd,
271 "show mgmt yang-xpath-subscription WORD$path",
272 SHOW_STR
273 MGMTD_STR
274 "Get YANG Backend Subscription\n"
275 "XPath expression specifying the YANG data path\n")
276 {
277 mgmt_be_xpath_subscr_info_write(vty, path);
278 return CMD_SUCCESS;
279 }
280
281 DEFPY(mgmt_load_config,
282 mgmt_load_config_cmd,
283 "mgmt load-config WORD$filepath <merge|replace>$type",
284 MGMTD_STR
285 "Load configuration onto Candidate Datastore\n"
286 "Full path of the file\n"
287 "Merge configuration with contents of Candidate Datastore\n"
288 "Replace the existing contents of Candidate datastore\n")
289 {
290 bool merge = type[0] == 'm' ? true : false;
291 struct mgmt_ds_ctx *ds_ctx;
292 int ret;
293
294 if (access(filepath, F_OK) == -1) {
295 vty_out(vty, "ERROR: File %s : %s\n", filepath,
296 strerror(errno));
297 return CMD_ERR_NO_FILE;
298 }
299
300 ds_ctx = mgmt_ds_get_ctx_by_id(mm, MGMTD_DS_CANDIDATE);
301 if (!ds_ctx) {
302 vty_out(vty, "ERROR: Could not access Candidate datastore!\n");
303 return CMD_ERR_NO_MATCH;
304 }
305
306 ret = mgmt_ds_load_config_from_file(ds_ctx, filepath, merge);
307 if (ret != 0)
308 vty_out(vty, "Error with parsing the file with error code %d\n",
309 ret);
310 return CMD_SUCCESS;
311 }
312
313 DEFPY(mgmt_save_config,
314 mgmt_save_config_cmd,
315 "mgmt save-config <candidate|running>$dsname WORD$filepath",
316 MGMTD_STR
317 "Save configuration from datastore\n"
318 "Candidate datastore\n"
319 "Running datastore\n"
320 "Full path of the file\n")
321 {
322 Mgmtd__DatastoreId datastore = mgmt_ds_name2id(dsname);
323 struct mgmt_ds_ctx *ds_ctx;
324 FILE *f;
325
326 ds_ctx = mgmt_ds_get_ctx_by_id(mm, datastore);
327 if (!ds_ctx) {
328 vty_out(vty, "ERROR: Could not access the '%s' datastore!\n",
329 dsname);
330 return CMD_ERR_NO_MATCH;
331 }
332
333 if (!filepath) {
334 vty_out(vty, "ERROR: No file path mentioned!\n");
335 return CMD_ERR_NO_MATCH;
336 }
337
338 f = fopen(filepath, "w");
339 if (!f) {
340 vty_out(vty, "Could not open file pointed by filepath %s\n",
341 filepath);
342 return CMD_SUCCESS;
343 }
344
345 mgmt_ds_dump_tree(vty, ds_ctx, "/", f, LYD_JSON);
346
347 fclose(f);
348
349 return CMD_SUCCESS;
350 }
351
352 DEFPY(show_mgmt_cmt_hist,
353 show_mgmt_cmt_hist_cmd,
354 "show mgmt commit-history",
355 SHOW_STR
356 MGMTD_STR
357 "Show commit history\n")
358 {
359 show_mgmt_cmt_history(vty);
360 return CMD_SUCCESS;
361 }
362
363 DEFPY(mgmt_rollback,
364 mgmt_rollback_cmd,
365 "mgmt rollback <commit-id WORD$commit | last [(1-10)]$last>",
366 MGMTD_STR
367 "Rollback commits\n"
368 "Rollback to commit ID\n"
369 "Commit-ID\n"
370 "Rollbak n commits\n"
371 "Number of commits\n")
372 {
373 if (commit)
374 mgmt_history_rollback_by_id(vty, commit);
375 else
376 mgmt_history_rollback_n(vty, last);
377
378 return CMD_SUCCESS;
379 }
380
381 static int config_write_mgmt_debug(struct vty *vty);
382 static struct cmd_node debug_node = {
383 .name = "debug",
384 .node = DEBUG_NODE,
385 .prompt = "",
386 .config_write = config_write_mgmt_debug,
387 };
388
389 static int config_write_mgmt_debug_helper(struct vty *vty, bool config)
390 {
391 int n = mgmt_debug_be + mgmt_debug_fe + mgmt_debug_ds + mgmt_debug_txn;
392 if (!n)
393 return 0;
394
395 if (config && mgmt_debug_be && mgmt_debug_fe && mgmt_debug_ds &&
396 mgmt_debug_txn) {
397 vty_out(vty, "debug mgmt all\n");
398 return 0;
399 }
400
401 vty_out(vty, "debug mgmt");
402 if (mgmt_debug_be)
403 vty_out(vty, " backend");
404 if (mgmt_debug_ds)
405 vty_out(vty, " datastore");
406 if (mgmt_debug_fe)
407 vty_out(vty, " frontend");
408 if (mgmt_debug_txn)
409 vty_out(vty, " transaction");
410
411 vty_out(vty, "\n");
412
413 return 0;
414 }
415
416 static int config_write_mgmt_debug(struct vty *vty)
417 {
418 return config_write_mgmt_debug_helper(vty, true);
419 }
420
421 DEFUN_NOSH(show_debugging_mgmt, show_debugging_mgmt_cmd,
422 "show debugging [mgmt]", SHOW_STR DEBUG_STR "MGMT Information\n")
423 {
424 vty_out(vty, "MGMT debugging status:\n");
425
426 config_write_mgmt_debug_helper(vty, false);
427
428 cmd_show_lib_debugs(vty);
429
430 return CMD_SUCCESS;
431 }
432
433 DEFPY(debug_mgmt, debug_mgmt_cmd,
434 "[no$no] debug mgmt <all$all|{backend$be|datastore$ds|frontend$fe|transaction$txn}>",
435 NO_STR DEBUG_STR MGMTD_STR
436 "All debug\n"
437 "Back-end debug\n"
438 "Datastore debug\n"
439 "Front-end debug\n"
440 "Transaction debug\n")
441 {
442 bool set = !no;
443 if (all)
444 be = fe = ds = txn = set ? all : NULL;
445
446 if (be)
447 mgmt_debug_be = set;
448 if (ds)
449 mgmt_debug_ds = set;
450 if (fe)
451 mgmt_debug_fe = set;
452 if (txn)
453 mgmt_debug_txn = set;
454
455 return CMD_SUCCESS;
456 }
457
458 void mgmt_vty_init(void)
459 {
460 /*
461 * Initialize command handling from VTYSH connection.
462 * Call command initialization routines defined by
463 * backend components that are moved to new MGMTD infra
464 * here one by one.
465 */
466 #if HAVE_STATICD
467 extern void static_vty_init(void);
468 static_vty_init();
469 #endif
470
471 install_node(&debug_node);
472
473 install_element(VIEW_NODE, &show_mgmt_be_adapter_cmd);
474 install_element(VIEW_NODE, &show_mgmt_be_xpath_reg_cmd);
475 install_element(VIEW_NODE, &show_mgmt_fe_adapter_cmd);
476 install_element(VIEW_NODE, &show_mgmt_txn_cmd);
477 install_element(VIEW_NODE, &show_mgmt_ds_cmd);
478 install_element(VIEW_NODE, &show_mgmt_get_config_cmd);
479 install_element(VIEW_NODE, &show_mgmt_get_data_cmd);
480 install_element(VIEW_NODE, &show_mgmt_dump_data_cmd);
481 install_element(VIEW_NODE, &show_mgmt_map_xpath_cmd);
482 install_element(VIEW_NODE, &show_mgmt_cmt_hist_cmd);
483
484 install_element(CONFIG_NODE, &mgmt_commit_cmd);
485 install_element(CONFIG_NODE, &mgmt_set_config_data_cmd);
486 install_element(CONFIG_NODE, &mgmt_delete_config_data_cmd);
487 install_element(CONFIG_NODE, &mgmt_load_config_cmd);
488 install_element(CONFIG_NODE, &mgmt_save_config_cmd);
489 install_element(CONFIG_NODE, &mgmt_rollback_cmd);
490
491 install_element(VIEW_NODE, &debug_mgmt_cmd);
492 install_element(CONFIG_NODE, &debug_mgmt_cmd);
493
494 /* Enable view */
495 install_element(ENABLE_NODE, &mgmt_performance_measurement_cmd);
496 install_element(ENABLE_NODE, &mgmt_reset_performance_stats_cmd);
497
498 install_element(ENABLE_NODE, &show_debugging_mgmt_cmd);
499
500 /*
501 * TODO: Register and handlers for auto-completion here.
502 */
503 }