8
8
import re
9
9
import subprocess
10
10
import sys
11
+ import ipaddr
11
12
12
13
import click
13
14
from click_default_group import DefaultGroup
@@ -188,7 +189,7 @@ def get_routing_stack():
188
189
routing_stack = get_routing_stack ()
189
190
190
191
191
- def run_command (command , display_cmd = False ):
192
+ def run_command (command , display_cmd = False , return_cmd = False ):
192
193
if display_cmd :
193
194
click .echo (click .style ("Command: " , fg = 'cyan' ) + click .style (command , fg = 'green' ))
194
195
@@ -201,6 +202,9 @@ def run_command(command, display_cmd=False):
201
202
proc = subprocess .Popen (command , shell = True , stdout = subprocess .PIPE )
202
203
203
204
while True :
205
+ if return_cmd :
206
+ output = proc .communicate ()[0 ].decode ("utf-8" )
207
+ return output
204
208
output = proc .stdout .readline ()
205
209
if output == "" and proc .poll () is not None :
206
210
break
@@ -393,6 +397,146 @@ def run_command_in_alias_mode(command):
393
397
sys .exit (rc )
394
398
395
399
400
+ def get_bgp_summary_extended (command_output ):
401
+ """
402
+ Adds Neighbor name to the show ip[v6] bgp summary command
403
+ :param command: command to get bgp summary
404
+ """
405
+ static_neighbors , dynamic_neighbors = get_bgp_neighbors_dict ()
406
+ modified_output = []
407
+ my_list = iter (command_output .splitlines ())
408
+ for element in my_list :
409
+ if element .startswith ("Neighbor" ):
410
+ element = "{}\t NeighborName" .format (element )
411
+ modified_output .append (element )
412
+ elif not element or element .startswith ("Total number " ):
413
+ modified_output .append (element )
414
+ elif re .match (r"(\*?([0-9A-Fa-f]{1,4}:|\d+.\d+.\d+.\d+))" , element .split ()[0 ]):
415
+ first_element = element .split ()[0 ]
416
+ ip = first_element [1 :] if first_element .startswith ("*" ) else first_element
417
+ name = get_bgp_neighbor_ip_to_name (ip , static_neighbors , dynamic_neighbors )
418
+ if len (element .split ()) == 1 :
419
+ modified_output .append (element )
420
+ element = next (my_list )
421
+ element = "{}\t {}" .format (element , name )
422
+ modified_output .append (element )
423
+ else :
424
+ modified_output .append (element )
425
+ click .echo ("\n " .join (modified_output ))
426
+
427
+
428
+ def connect_config_db ():
429
+ """
430
+ Connects to config_db
431
+ """
432
+ config_db = ConfigDBConnector ()
433
+ config_db .connect ()
434
+ return config_db
435
+
436
+
437
+ def get_neighbor_dict_from_table (db ,table_name ):
438
+ """
439
+ returns a dict with bgp neighbor ip as key and neighbor name as value
440
+ :param table_name: config db table name
441
+ :param db: config_db
442
+ """
443
+ neighbor_dict = {}
444
+ neighbor_data = db .get_table (table_name )
445
+ try :
446
+ for entry in neighbor_data .keys ():
447
+ neighbor_dict [entry ] = neighbor_data [entry ].get (
448
+ 'name' ) if 'name' in neighbor_data [entry ].keys () else 'NotAvailable'
449
+ return neighbor_dict
450
+ except :
451
+ return neighbor_dict
452
+
453
+
454
+ def is_ipv4_address (ipaddress ):
455
+ """
456
+ Checks if given ip is ipv4
457
+ :param ipaddress: unicode ipv4
458
+ :return: bool
459
+ """
460
+ try :
461
+ ipaddress .IPv4Address (ipaddress )
462
+ return True
463
+ except ipaddress .AddressValueError as err :
464
+ return False
465
+
466
+
467
+ def is_ipv6_address (ipaddress ):
468
+ """
469
+ Checks if given ip is ipv6
470
+ :param ipaddress: unicode ipv6
471
+ :return: bool
472
+ """
473
+ try :
474
+ ipaddress .IPv6Address (ipaddress )
475
+ return True
476
+ except ipaddress .AddressValueError as err :
477
+ return False
478
+
479
+
480
+ def get_dynamic_neighbor_subnet (db ):
481
+ """
482
+ Returns dict of description and subnet info from bgp_peer_range table
483
+ :param db: config_db
484
+ """
485
+ dynamic_neighbor = {}
486
+ v4_subnet = {}
487
+ v6_subnet = {}
488
+ neighbor_data = db .get_table ('BGP_PEER_RANGE' )
489
+ try :
490
+ for entry in neighbor_data .keys ():
491
+ new_key = neighbor_data [entry ]['ip_range' ][0 ]
492
+ new_value = neighbor_data [entry ]['name' ]
493
+ if is_ipv4_address (unicode (neighbor_data [entry ]['src_address' ])):
494
+ v4_subnet [new_key ] = new_value
495
+ elif is_ipv6_address (unicode (neighbor_data [entry ]['src_address' ])):
496
+ v6_subnet [new_key ] = new_value
497
+ dynamic_neighbor ["v4" ] = v4_subnet
498
+ dynamic_neighbor ["v6" ] = v6_subnet
499
+ return dynamic_neighbor
500
+ except :
501
+ return neighbor_data
502
+
503
+
504
+ def get_bgp_neighbors_dict ():
505
+ """
506
+ Uses config_db to get the bgp neighbors and names in dictionary format
507
+ :return:
508
+ """
509
+ dynamic_neighbors = {}
510
+ config_db = connect_config_db ()
511
+ static_neighbors = get_neighbor_dict_from_table (config_db , 'BGP_NEIGHBOR' )
512
+ bgp_monitors = get_neighbor_dict_from_table (config_db , 'BGP_MONITORS' )
513
+ static_neighbors .update (bgp_monitors )
514
+ dynamic_neighbors = get_dynamic_neighbor_subnet (config_db )
515
+ return static_neighbors , dynamic_neighbors
516
+
517
+
518
+ def get_bgp_neighbor_ip_to_name (ip , static_neighbors , dynamic_neighbors ):
519
+ """
520
+ return neighbor name for the ip provided
521
+ :param ip: ip address unicode
522
+ :param static_neighbors: statically defined bgp neighbors dict
523
+ :param dynamic_neighbors: subnet of dynamically defined neighbors dict
524
+ :return: name of neighbor
525
+ """
526
+ if ip in static_neighbors .keys ():
527
+ return static_neighbors [ip ]
528
+ elif is_ipv4_address (unicode (ip )):
529
+ for subnet in dynamic_neighbors ["v4" ].keys ():
530
+ if ipaddress .IPv4Address (unicode (ip )) in ipaddress .IPv4Network (unicode (subnet )):
531
+ return dynamic_neighbors ["v4" ][subnet ]
532
+ elif is_ipv6_address (unicode (ip )):
533
+ for subnet in dynamic_neighbors ["v6" ].keys ():
534
+ if ipaddress .IPv6Address (unicode (ip )) in ipaddress .IPv6Network (unicode (subnet )):
535
+ return dynamic_neighbors ["v6" ][subnet ]
536
+ else :
537
+ return "NotAvailable"
538
+
539
+
396
540
CONTEXT_SETTINGS = dict (help_option_names = ['-h' , '--help' , '-?' ])
397
541
398
542
#
0 commit comments