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