]> git.proxmox.com Git - mirror_frr.git/blame - mgmtd/mgmt_vty.c
Merge pull request #13148 from samanvithab/bgp_mem_leak_fix
[mirror_frr.git] / mgmtd / mgmt_vty.c
CommitLineData
1c84efe4
CH
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"
7d65b7b7
CH
14#include "mgmtd/mgmt_be_server.h"
15#include "mgmtd/mgmt_be_adapter.h"
ef43a632
CH
16#include "mgmtd/mgmt_fe_server.h"
17#include "mgmtd/mgmt_fe_adapter.h"
1c84efe4 18#include "mgmtd/mgmt_ds.h"
74335ceb 19#include "mgmtd/mgmt_history.h"
1c84efe4 20
1c84efe4 21#include "mgmtd/mgmt_vty_clippy.c"
ef43a632 22
7d65b7b7
CH
23DEFPY(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
36DEFPY(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
ef43a632
CH
48DEFPY(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}
1c84efe4 60
74335ceb
YR
61DEFPY_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
76DEFPY(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
87DEFPY(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
1c84efe4
CH
100DEFPY(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
ef43a632
CH
127DEFPY(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
144DEFPY(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
163DEFPY(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
182DEFPY(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
202DEFPY(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
1c84efe4
CH
222DEFPY(show_mgmt_dump_data,
223 show_mgmt_dump_data_cmd,
ef43a632 224 "show mgmt datastore-contents [candidate|operational|running]$dsname [xpath WORD$path] [file WORD$filepath] <json|xml>$fmt",
1c84efe4
CH
225 SHOW_STR
226 MGMTD_STR
227 "Get Datastore contents from a specific datastore\n"
ef43a632
CH
228 "Candidate datastore (default)\n"
229 "Operational datastore\n"
230 "Running datastore\n"
1c84efe4
CH
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"
ef43a632
CH
235 "json output\n"
236 "xml output\n")
1c84efe4 237{
1c84efe4 238 struct mgmt_ds_ctx *ds_ctx;
ef43a632 239 Mgmtd__DatastoreId datastore = MGMTD_DS_CANDIDATE;
1c84efe4
CH
240 LYD_FORMAT format = fmt[0] == 'j' ? LYD_JSON : LYD_XML;
241 FILE *f = NULL;
242
ef43a632
CH
243 if (datastore)
244 datastore = mgmt_ds_name2id(dsname);
1c84efe4
CH
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
7d65b7b7
CH
269DEFPY(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
1c84efe4
CH
281DEFPY(mgmt_load_config,
282 mgmt_load_config_cmd,
ef43a632 283 "mgmt load-config WORD$filepath <merge|replace>$type",
1c84efe4
CH
284 MGMTD_STR
285 "Load configuration onto Candidate Datastore\n"
1c84efe4
CH
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{
ef43a632 290 bool merge = type[0] == 'm' ? true : false;
1c84efe4 291 struct mgmt_ds_ctx *ds_ctx;
ef43a632 292 int ret;
1c84efe4
CH
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
1c84efe4
CH
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
313DEFPY(mgmt_save_config,
314 mgmt_save_config_cmd,
ef43a632 315 "mgmt save-config <candidate|running>$dsname WORD$filepath",
1c84efe4
CH
316 MGMTD_STR
317 "Save configuration from datastore\n"
ef43a632
CH
318 "Candidate datastore\n"
319 "Running datastore\n"
1c84efe4
CH
320 "Full path of the file\n")
321{
ef43a632 322 Mgmtd__DatastoreId datastore = mgmt_ds_name2id(dsname);
1c84efe4 323 struct mgmt_ds_ctx *ds_ctx;
1c84efe4
CH
324 FILE *f;
325
1c84efe4
CH
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
74335ceb
YR
352DEFPY(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
363DEFPY(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
381static int config_write_mgmt_debug(struct vty *vty);
382static struct cmd_node debug_node = {
383 .name = "debug",
384 .node = DEBUG_NODE,
385 .prompt = "",
386 .config_write = config_write_mgmt_debug,
387};
388
1c84efe4
CH
389static int config_write_mgmt_debug(struct vty *vty)
390{
391 int n = mgmt_debug_be + mgmt_debug_fe + mgmt_debug_ds + mgmt_debug_txn;
392 if (!n)
393 return 0;
394 if (n == 4) {
395 vty_out(vty, "debug mgmt all\n");
396 return 0;
397 }
398
399 vty_out(vty, "debug mgmt");
400 if (mgmt_debug_be)
401 vty_out(vty, " backend");
402 if (mgmt_debug_ds)
403 vty_out(vty, " datastore");
404 if (mgmt_debug_fe)
405 vty_out(vty, " frontend");
406 if (mgmt_debug_txn)
407 vty_out(vty, " transaction");
408
409 vty_out(vty, "\n");
410
411 return 0;
412}
1c84efe4
CH
413
414DEFPY(debug_mgmt,
415 debug_mgmt_cmd,
416 "[no$no] debug mgmt <all$all|{backend$be|datastore$ds|frontend$fe|transaction$txn}>",
417 NO_STR
418 DEBUG_STR
419 MGMTD_STR
420 "All debug\n"
421 "Back-end debug\n"
422 "Datastore debug\n"
423 "Front-end debug\n"
424 "Transaction debug\n")
425{
426 bool set = !no;
427 if (all)
428 be = fe = ds = txn = set ? all : NULL;
429
430 if (be)
431 mgmt_debug_be = set;
432 if (ds)
433 mgmt_debug_ds = set;
434 if (fe)
435 mgmt_debug_fe = set;
436 if (txn)
437 mgmt_debug_txn = set;
438
439 return CMD_SUCCESS;
440}
441
442void mgmt_vty_init(void)
443{
7d65b7b7
CH
444 /*
445 * Initialize command handling from VTYSH connection.
446 * Call command initialization routines defined by
447 * backend components that are moved to new MGMTD infra
448 * here one by one.
449 */
7d65b7b7
CH
450#if HAVE_STATICD
451 extern void static_vty_init(void);
452 static_vty_init();
7d65b7b7
CH
453#endif
454
1c84efe4
CH
455 install_node(&debug_node);
456
7d65b7b7
CH
457 install_element(VIEW_NODE, &show_mgmt_be_adapter_cmd);
458 install_element(VIEW_NODE, &show_mgmt_be_xpath_reg_cmd);
ef43a632 459 install_element(VIEW_NODE, &show_mgmt_fe_adapter_cmd);
74335ceb 460 install_element(VIEW_NODE, &show_mgmt_txn_cmd);
1c84efe4 461 install_element(VIEW_NODE, &show_mgmt_ds_cmd);
ef43a632
CH
462 install_element(VIEW_NODE, &show_mgmt_get_config_cmd);
463 install_element(VIEW_NODE, &show_mgmt_get_data_cmd);
1c84efe4 464 install_element(VIEW_NODE, &show_mgmt_dump_data_cmd);
7d65b7b7 465 install_element(VIEW_NODE, &show_mgmt_map_xpath_cmd);
74335ceb 466 install_element(VIEW_NODE, &show_mgmt_cmt_hist_cmd);
1c84efe4 467
ef43a632
CH
468 install_element(CONFIG_NODE, &mgmt_commit_cmd);
469 install_element(CONFIG_NODE, &mgmt_set_config_data_cmd);
470 install_element(CONFIG_NODE, &mgmt_delete_config_data_cmd);
1c84efe4
CH
471 install_element(CONFIG_NODE, &mgmt_load_config_cmd);
472 install_element(CONFIG_NODE, &mgmt_save_config_cmd);
74335ceb 473 install_element(CONFIG_NODE, &mgmt_rollback_cmd);
1c84efe4
CH
474
475 install_element(VIEW_NODE, &debug_mgmt_cmd);
476 install_element(CONFIG_NODE, &debug_mgmt_cmd);
477
74335ceb
YR
478 /* Enable view */
479 install_element(ENABLE_NODE, &mgmt_performance_measurement_cmd);
480 install_element(ENABLE_NODE, &mgmt_reset_performance_stats_cmd);
481
1c84efe4 482 /*
74335ceb 483 * TODO: Register and handlers for auto-completion here.
1c84efe4
CH
484 */
485}