def neighbors(ipaddress, info_type, namespace): """Show IP (IPv4) BGP neighbors""" command = 'show ip bgp neighbor' if ipaddress is not None: if not bgp_util.is_ipv4_address(ipaddress): ctx = click.get_current_context() ctx.fail("{} is not valid ipv4 address\n".format(ipaddress)) try: actual_namespace = bgp_util.get_namespace_for_bgp_neighbor( ipaddress) if namespace is not None and namespace != actual_namespace: click.echo( "[WARNING]: bgp neighbor {} is present in namespace {} not in {}" .format(ipaddress, actual_namespace, namespace)) # save the namespace in which the bgp neighbor is configured namespace = actual_namespace command += ' {}'.format(ipaddress) # info_type is only valid if ipaddress is specified if info_type is not None: command += ' {}'.format(info_type) except ValueError as err: ctx = click.get_current_context() ctx.fail("{}\n".format(err)) ns_list = multi_asic.get_namespace_list(namespace) output = "" for ns in ns_list: output += bgp_util.run_bgp_command(command, ns) click.echo(output.rstrip('\n'))
def neighbors(ipaddress, info_type, namespace): """Show IPv6 BGP neighbors""" if ipaddress is not None: if not bgp_util.is_ipv6_address(ipaddress): ctx = click.get_current_context() ctx.fail("{} is not valid ipv6 address\n".format(ipaddress)) try: actual_namespace = bgp_util.get_namespace_for_bgp_neighbor( ipaddress) if namespace is not None and namespace != actual_namespace: click.echo( "bgp neighbor {} is present in namespace {} not in {}" .format(ipaddress, actual_namespace, namespace)) # save the namespace in which the bgp neighbor is configured namespace = actual_namespace except ValueError as err: ctx = click.get_current_context() ctx.fail("{}\n".format(err)) else: ipaddress = "" info_type = "" if info_type is None else info_type command = 'show bgp ipv6 neighbor {} {}'.format( ipaddress, info_type) ns_list = multi_asic.get_namespace_list(namespace) output = "" for ns in ns_list: output += bgp_util.run_bgp_command(command, ns) click.echo(output.rstrip('\n'))
def network(ipaddress, info_type, namespace): """Show IP (IPv4) BGP network""" if multi_asic.is_multi_asic() and namespace not in multi_asic.get_namespace_list(): ctx = click.get_current_context() ctx.fail('-n/--namespace option required. provide namespace from list {}'\ .format(multi_asic.get_namespace_list())) command = 'show ip bgp' if ipaddress is not None: if '/' in ipaddress: # For network prefixes then this all info_type(s) are available pass else: # For an ipaddress then check info_type, exit if specified option doesn't work. if info_type in ['longer-prefixes']: click.echo('The parameter option: "{}" only available if passing a network prefix'.format(info_type)) click.echo("EX: 'show ip bgp network 10.0.0.0/24 longer-prefixes'") raise click.Abort() command += ' {}'.format(ipaddress) # info_type is only valid if prefix/ipaddress is specified if info_type is not None: command += ' {}'.format(info_type) output = bgp_util.run_bgp_command(command, namespace) click.echo(output.rstrip('\n'))
def show_routes(args, namespace, display, verbose, ipver): import utilities_common.bgp_util as bgp_util """Show IPv4/IPV6 routing table""" filter_back_end = False if display is None: if multi_asic.is_multi_asic(): display = constants.DISPLAY_EXTERNAL filter_back_end = True else: if multi_asic.is_multi_asic(): if display not in multi_asic_util.multi_asic_display_choices(): print("dislay option '{}' is not a valid option.".format(display)) return else: if display == constants.DISPLAY_EXTERNAL: filter_back_end = True else: if display not in ['frontend', 'all']: print("dislay option '{}' is not a valid option.".format(display)) return device = multi_asic_util.MultiAsic(display, namespace) arg_strg = "" found_json = 0 found_other_parms = 0 ns_l = [] print_ns_str = False filter_by_ip = False asic_cnt = 0 try: ns_l = device.get_ns_list_based_on_options() except ValueError: print("namespace '{}' is not valid. valid name spaces are:\n{}".format(namespace, multi_asic_util.multi_asic_ns_choices())) return asic_cnt = len(ns_l) if asic_cnt > 1 and display == constants.DISPLAY_ALL: print_ns_str = True if namespace is not None: if not multi_asic.is_multi_asic(): print("namespace option is not applicable for non-multi-asic platform") return # build the filter set only if necessary if filter_back_end: back_end_intf_set = multi_asic.get_back_end_interface_set() else: back_end_intf_set = None # get all the other arguments except json that needs to be the last argument of the cmd if present # For Multi-ASIC platform the support for combining routes will be supported for "show ip/v6 route" # and optionally with specific IP address as parameter and the json option. If any other option is # specified, the handling will always be handled by the specific namespace FRR. for arg in args: arg_strg += str(arg) + " " if str(arg) == "json": found_json = 1 else: try: filter_by_ip = ipaddress.ip_network(arg) except ValueError: # Not ip address just ignore it found_other_parms = 1 if multi_asic.is_multi_asic(): if not found_json and not found_other_parms: arg_strg += "json" combined_route = {} for ns in ns_l: # Need to add "ns" to form bgpX so it is sent to the correct bgpX docker to handle the request # If not MultiASIC, skip namespace argument cmd = "show {} route {}".format(ipver, arg_strg) if multi_asic.is_multi_asic(): output = bgp_util.run_bgp_command(cmd, ns) else: output = bgp_util.run_bgp_command(cmd) print("{}".format(output)) return # in case no output or something went wrong with user specified cmd argument(s) error it out # error from FRR always start with character "%" if output == "": return if output[0] == "%": # remove the "json" keyword that was added by this handler to show original cmd user specified json_str = output[-5:-1] if json_str == "json": error_msg = output[:-5] else: error_msg = output print(error_msg) return # Multi-asic show ip route with additional parms are handled by going to FRR directly and get those outputs from each namespace if found_other_parms: print("{}:".format(ns)) print(output) continue route_info = json.loads(output) if filter_back_end or print_ns_str: # clean up the dictionary to remove all the nexthops that are back-end interface process_route_info(route_info, device, filter_back_end, print_ns_str, asic_cnt, ns, combined_route, back_end_intf_set) else: combined_route = route_info if not combined_route: return if not found_json: #print out the header if this is not a json request if not filter_by_ip: print_show_ip_route_hdr() if print_ns_str: for name_space, ns_route in sorted(combined_route.items()): print("{}:".format(name_space)) print_ip_routes(ns_route, filter_by_ip) else: print_ip_routes(combined_route, filter_by_ip) else: new_string = json.dumps(combined_route,sort_keys=True, indent=4) print(new_string)