def tablelize(keys, data): table = [] for k in natsorted(keys): members = set(data[k].get('members', [])) for (vlan, interface_name) in member_data: if vlan == k: members.add(interface_name) for m in members: r = [] r.append(k) r.append(data[k]['vlanid']) if clicommon.get_interface_naming_mode() == "alias": alias = clicommon.InterfaceAliasConverter( db).name_to_alias(m) r.append(alias) else: r.append(m) entry = db.cfgdb.get_entry('VLAN_MEMBER', (k, m)) mode = entry.get('tagging_mode') if mode is None: r.append('?') else: r.append(mode) table.append(r) return table
def del_vlan_member(db, vid, port): """Delete VLAN member""" ctx = click.get_current_context() log.log_info("'vlan member del {} {}' executing...".format(vid, port)) if not clicommon.is_vlanid_in_range(vid): ctx.fail("Invalid VLAN ID {} (1-4094)".format(vid)) vlan = 'Vlan{}'.format(vid) if clicommon.check_if_vlanid_exist(db.cfgdb, vlan) == False: ctx.fail("{} does not exist".format(vlan)) if clicommon.get_interface_naming_mode() == "alias": alias = port iface_alias_converter = clicommon.InterfaceAliasConverter(db) port = iface_alias_converter.alias_to_name(alias) if port is None: ctx.fail("cannot find port name for alias {}".format(alias)) if not clicommon.is_port_vlan_member(db.cfgdb, port, vlan): ctx.fail("{} is not a member of {}".format(port, vlan)) db.cfgdb.set_entry('VLAN_MEMBER', (vlan, port), None)
def run_command(command, display_cmd=False, return_cmd=False): if display_cmd: click.echo( click.style("Command: ", fg='cyan') + click.style(command, fg='green')) # No conversion needed for intfutil commands as it already displays # both SONiC interface name and alias name for all interfaces. if clicommon.get_interface_naming_mode( ) == "alias" and not command.startswith("intfutil"): clicommon.run_command_in_alias_mode(command) raise sys.exit(0) proc = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE) while True: if return_cmd: output = proc.communicate()[0] return output output = proc.stdout.readline() if output == "" and proc.poll() is not None: break if output: click.echo(output.rstrip('\n')) rc = proc.poll() if rc != 0: sys.exit(rc)
def tablelize(keys, data): table = [] for k in natsorted(keys): if 'members' not in data[k] : r = [] r.append(k) r.append(data[k]['vlanid']) table.append(r) continue for m in data[k].get('members', []): r = [] r.append(k) r.append(data[k]['vlanid']) if clicommon.get_interface_naming_mode() == "alias": alias = iface_alias_converter.name_to_alias(m) r.append(alias) else: r.append(m) entry = db.cfgdb.get_entry('VLAN_MEMBER', (k, m)) mode = entry.get('tagging_mode') if mode is None: r.append('?') else: r.append(mode) table.append(r) return table
def interfaces(): """Show interfaces IPv4 address""" import netaddr header = [ 'Interface', 'Master', 'IPv4 address/mask', 'Admin/Oper', 'BGP Neighbor', 'Neighbor IP' ] data = [] bgp_peer = get_bgp_peer() interfaces = natsorted(netifaces.interfaces()) for iface in interfaces: ipaddresses = netifaces.ifaddresses(iface) if netifaces.AF_INET in ipaddresses: ifaddresses = [] neighbor_info = [] for ipaddr in ipaddresses[netifaces.AF_INET]: neighbor_name = 'N/A' neighbor_ip = 'N/A' local_ip = str(ipaddr['addr']) netmask = netaddr.IPAddress(ipaddr['netmask']).netmask_bits() ifaddresses.append(["", local_ip + "/" + str(netmask)]) try: neighbor_name = bgp_peer[local_ip][0] neighbor_ip = bgp_peer[local_ip][1] except Exception: pass neighbor_info.append([neighbor_name, neighbor_ip]) if len(ifaddresses) > 0: admin = get_if_admin_state(iface) if admin == "up": oper = get_if_oper_state(iface) else: oper = "down" master = get_if_master(iface) if clicommon.get_interface_naming_mode() == "alias": iface = iface_alias_converter.name_to_alias(iface) data.append([ iface, master, ifaddresses[0][1], admin + "/" + oper, neighbor_info[0][0], neighbor_info[0][1] ]) neighbor_info.pop(0) for ifaddr in ifaddresses[1:]: data.append([ "", "", ifaddr[1], admin + "/" + oper, neighbor_info[0][0], neighbor_info[0][1] ]) neighbor_info.pop(0) print( tabulate(data, header, tablefmt="simple", stralign='left', missingval=""))
def expected(db, interfacename): """Show expected neighbor information by interfaces""" neighbor_dict = db.cfgdb.get_table("DEVICE_NEIGHBOR") if neighbor_dict is None: click.echo("DEVICE_NEIGHBOR information is not present.") return neighbor_metadata_dict = db.cfgdb.get_table("DEVICE_NEIGHBOR_METADATA") if neighbor_metadata_dict is None: click.echo("DEVICE_NEIGHBOR_METADATA information is not present.") return #Swap Key and Value from interface: name to name: interface device2interface_dict = {} for port in natsorted(neighbor_dict.keys()): temp_port = port if clicommon.get_interface_naming_mode() == "alias": port = clicommon.InterfaceAliasConverter().name_to_alias(port) neighbor_dict[port] = neighbor_dict.pop(temp_port) device2interface_dict[neighbor_dict[port]['name']] = { 'localPort': port, 'neighborPort': neighbor_dict[port]['port'] } header = [ 'LocalPort', 'Neighbor', 'NeighborPort', 'NeighborLoopback', 'NeighborMgmt', 'NeighborType' ] body = [] if interfacename: try: device = neighbor_dict[interfacename]['name'] body.append([ interfacename, device, neighbor_dict[interfacename]['port'], neighbor_metadata_dict[device]['lo_addr'], neighbor_metadata_dict[device]['mgmt_addr'], neighbor_metadata_dict[device]['type'] ]) except KeyError: click.echo( "No neighbor information available for interface {}".format( interfacename)) return else: for port in natsorted(neighbor_dict.keys()): try: device = neighbor_dict[port]['name'] body.append([ port, device, neighbor_dict[port]['port'], neighbor_metadata_dict[device]['lo_addr'], neighbor_metadata_dict[device]['mgmt_addr'], neighbor_metadata_dict[device]['type'] ]) except KeyError: pass click.echo(tabulate(body, header))
def asymmetric(interface): """Show asymmetric pfc""" cmd = 'pfc show asymmetric' if interface is not None and clicommon.get_interface_naming_mode() == "alias": interface = iface_alias_converter.alias_to_name(interface) if interface is not None: cmd += ' {0}'.format(interface) run_command(cmd)
def priority(interface): """Show pfc priority""" cmd = 'pfc show priority' if interface is not None and clicommon.get_interface_naming_mode() == "alias": interface = iface_alias_converter.alias_to_name(interface) if interface is not None: cmd += ' {0}'.format(interface) run_command(cmd)
def neighbors(interfacename, verbose): """Show LLDP neighbors""" cmd = "sudo lldpshow -d" if interfacename is not None: if clicommon.get_interface_naming_mode() == "alias": interfacename = iface_alias_converter.alias_to_name(interfacename) cmd += " -p {}".format(interfacename) run_command(cmd, display_cmd=verbose)
def try_convert_interfacename_from_alias(ctx, interfacename): """try to convert interface name from alias""" if clicommon.get_interface_naming_mode() == "alias": alias = interfacename interfacename = clicommon.InterfaceAliasConverter().alias_to_name(alias) # TODO: ideally alias_to_name should return None when it cannot find # the port name for the alias if interfacename == alias: ctx.fail("cannot find interface name for alias {}".format(alias)) return interfacename
def counters(interfacename, verbose): """Show queue counters""" cmd = "queuestat" if interfacename is not None: if clicommon.get_interface_naming_mode() == "alias": interfacename = iface_alias_converter.alias_to_name(interfacename) if interfacename is not None: cmd += " -p {}".format(interfacename) run_command(cmd, display_cmd=verbose)
def add_vlan_member(db, vid, port, untagged): """Add VLAN member""" ctx = click.get_current_context() log.log_info("'vlan member add {} {}' executing...".format(vid, port)) if not clicommon.is_vlanid_in_range(vid): ctx.fail("Invalid VLAN ID {} (1-4094)".format(vid)) vlan = 'Vlan{}'.format(vid) if clicommon.check_if_vlanid_exist(db.cfgdb, vlan) == False: ctx.fail("{} does not exist".format(vlan)) if clicommon.get_interface_naming_mode() == "alias": alias = port iface_alias_converter = clicommon.InterfaceAliasConverter(db) port = iface_alias_converter.alias_to_name(alias) if port is None: ctx.fail("cannot find port name for alias {}".format(alias)) if clicommon.is_port_mirror_dst_port(db.cfgdb, port): ctx.fail("{} is configured as mirror destination port".format(port)) if clicommon.is_port_vlan_member(db.cfgdb, port, vlan): ctx.fail("{} is already a member of {}".format(port, vlan)) if clicommon.is_valid_port(db.cfgdb, port): is_port = True elif clicommon.is_valid_portchannel(db.cfgdb, port): is_port = False else: ctx.fail("{} does not exist".format(port)) if (is_port and clicommon.is_port_router_interface(db.cfgdb, port)) or \ (not is_port and clicommon.is_pc_router_interface(db.cfgdb, port)): ctx.fail("{} is a router interface!".format(port)) portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER') if (is_port and clicommon.interface_is_in_portchannel( portchannel_member_table, port)): ctx.fail("{} is part of portchannel!".format(port)) if (clicommon.interface_is_untagged_member(db.cfgdb, port) and untagged): ctx.fail("{} is already untagged member!".format(port)) db.cfgdb.set_entry('VLAN_MEMBER', (vlan, port), {'tagging_mode': "untagged" if untagged else "tagged"})
def arp(ipaddress, iface, verbose): """Show IP ARP table""" cmd = "nbrshow -4" if ipaddress is not None: cmd += " -ip {}".format(ipaddress) if iface is not None: if clicommon.get_interface_naming_mode() == "alias": if not ((iface.startswith("PortChannel")) or (iface.startswith("eth"))): iface = iface_alias_converter.alias_to_name(iface) cmd += " -if {}".format(iface) run_command(cmd, display_cmd=verbose)
def get_teamshow_result(self): """ Get teamshow results by parsing the output of teamdctl and combining port channel status. """ for team in self.teams: info = {} team_id = self.get_team_id(team) if team_id not in self.teamsraw: info['protocol'] = 'N/A' self.summary[team_id] = info self.summary[team_id]['ports'] = '' continue state = self.teamsraw[team_id] info['protocol'] = "LACP" info['protocol'] += "(A)" if state['runner.active'] == "true" else '(I)' portchannel_status = self.get_portchannel_status(team) if portchannel_status is None: info['protocol'] += '(N/A)' elif portchannel_status.lower() == 'up': info['protocol'] += '(Up)' elif portchannel_status.lower() == 'down': info['protocol'] += '(Dw)' else: info['protocol'] += '(N/A)' info['ports'] = "" member_keys = self.db.keys(self.db.STATE_DB, PORT_CHANNEL_MEMBER_STATE_TABLE_PREFIX+team+'|*') if member_keys is None: info['ports'] = 'N/A' else: ports = [key[len(PORT_CHANNEL_MEMBER_STATE_TABLE_PREFIX+team+'|'):] for key in member_keys] for port in ports: status = self.get_portchannel_member_status(team, port) pstate = self.db.get_all(self.db.STATE_DB, PORT_CHANNEL_MEMBER_STATE_TABLE_PREFIX+team+'|'+port) selected = True if pstate['runner.aggregator.selected'] == "true" else False if clicommon.get_interface_naming_mode() == "alias": alias = clicommon.InterfaceAliasConverter(self.db2).name_to_alias(port) info["ports"] += alias + "(" else: info["ports"] += port + "(" info["ports"] += "S" if selected else "D" if status is None or (status == "enabled" and not selected) or (status == "disabled" and selected): info["ports"] += "*" info["ports"] += ") " self.summary[team_id] = info
def status(subinterfacename, verbose): """Show sub port interface status information""" cmd = "intfutil -c status" if subinterfacename is not None: sub_intf_sep_idx = subinterfacename.find(VLAN_SUB_INTERFACE_SEPARATOR) if sub_intf_sep_idx == -1: print("Invalid sub port interface name") return if clicommon.get_interface_naming_mode() == "alias": subinterfacename = iface_alias_converter.alias_to_name(subinterfacename) cmd += " -i {}".format(subinterfacename) else: cmd += " -i subport" run_command(cmd, display_cmd=verbose)
def config(db): data = db.cfgdb.get_table('VLAN') keys = list(data.keys()) member_data = db.cfgdb.get_table('VLAN_MEMBER') interface_naming_mode = clicommon.get_interface_naming_mode() iface_alias_converter = clicommon.InterfaceAliasConverter(db) def get_iface_name_for_display(member): name_for_display = member if interface_naming_mode == "alias" and member: name_for_display = iface_alias_converter.name_to_alias(member) return name_for_display def get_tagging_mode(vlan, member): if not member: return '' tagging_mode = db.cfgdb.get_entry('VLAN_MEMBER', (vlan, member)).get('tagging_mode') return '?' if tagging_mode is None else tagging_mode def tablelize(keys, data): table = [] for k in natsorted(keys): members = set([(vlan, member) for vlan, member in member_data if vlan == k] + [(k, member) for member in set(data[k].get('members', []))]) # vlan with no members if not members: members = [(k, '')] for vlan, member in natsorted(members): r = [ vlan, data[vlan]['vlanid'], get_iface_name_for_display(member), get_tagging_mode(vlan, member) ] table.append(r) return table header = ['Name', 'VID', 'Member', 'Mode'] click.echo(tabulate(tablelize(keys, data), header))
def del_port(db, port): """ Delete MACsec port """ ctx = click.get_current_context() if clicommon.get_interface_naming_mode() == "alias": alias = port iface_alias_converter = clicommon.InterfaceAliasConverter(db) port = iface_alias_converter.alias_to_name(alias) if port is None: ctx.fail("cannot find port name for alias {}".format(alias)) port_entry = db.cfgdb.get_entry('PORT', port) if len(port_entry) == 0: ctx.fail("port {} doesn't exist".format(port)) del port_entry['macsec'] db.cfgdb.set_entry("PORT", port, port_entry)
def mpls(ctx, interfacename): """Show Interface MPLS status""" appl_db = SonicV2Connector() appl_db.connect(appl_db.APPL_DB) if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) # Fetching data from appl_db for intfs keys = appl_db.keys(appl_db.APPL_DB, "INTF_TABLE:*") intfs_data = {} for key in keys if keys else []: tokens = key.split(":") # Skip INTF_TABLE entries with address information if len(tokens) != 2: continue if (interfacename is not None) and (interfacename != tokens[1]): continue mpls = appl_db.get(appl_db.APPL_DB, key, 'mpls') if mpls is None or mpls == '': intfs_data.update({tokens[1]: 'disable'}) else: intfs_data.update({tokens[1]: mpls}) header = ['Interface', 'MPLS State'] body = [] # Output name and alias for all interfaces for intf_name in natsorted(list(intfs_data.keys())): if clicommon.get_interface_naming_mode() == "alias": alias = clicommon.InterfaceAliasConverter().name_to_alias(intf_name) body.append([alias, intfs_data[intf_name]]) else: body.append([intf_name, intfs_data[intf_name]]) click.echo(tabulate(body, header))
def get_vlan_ports(ctx, vlan): cfg, db = ctx _, _, vlan_ports_data = cfg vlan_ports = [] iface_alias_converter = clicommon.InterfaceAliasConverter(db) # Here natsorting is important in relation to another # column which prints port tagging mode. # If we sort both in the same way using same keys # we will result in right order in both columns. # This should be fixed by cli code autogeneration tool # and we won't need this specific approach with # VlanBrief.COLUMNS anymore. for key in natsorted(list(vlan_ports_data.keys())): ports_key, ports_value = key if vlan != ports_key: continue if clicommon.get_interface_naming_mode() == "alias": ports_value = iface_alias_converter.name_to_alias(ports_value) vlan_ports.append(ports_value) return '\n'.join(vlan_ports)
def interface_name_is_valid(config_db, interface_name): """Check if the interface name is valid """ # If the input parameter config_db is None, derive it from interface. # In single ASIC platform, get_port_namespace() returns DEFAULT_NAMESPACE. if config_db is None: namespace = get_port_namespace(interface_name) if namespace is None: return False config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) config_db.connect() port_dict = config_db.get_table('PORT') port_channel_dict = config_db.get_table('PORTCHANNEL') sub_port_intf_dict = config_db.get_table('VLAN_SUB_INTERFACE') if clicommon.get_interface_naming_mode() == "alias": interface_name = interface_alias_to_name(config_db, interface_name) if interface_name is not None: if not port_dict: click.echo("port_dict is None!") raise click.Abort() for port_name in port_dict.keys(): if interface_name == port_name: return True if port_channel_dict: for port_channel_name in port_channel_dict.keys(): if interface_name == port_channel_name: return True if sub_port_intf_dict: for sub_port_intf_name in sub_port_intf_dict.keys(): if interface_name == sub_port_intf_name: return True return False
def naming_mode(verbose): """Show interface naming_mode status""" click.echo(clicommon.get_interface_naming_mode())
def brief(db, verbose): """Show all bridge information""" header = [ 'VLAN ID', 'IP Address', 'Ports', 'Port Tagging', 'DHCP Helper Address', 'Proxy ARP' ] body = [] # Fetching data from config db for VLAN, VLAN_INTERFACE and VLAN_MEMBER vlan_dhcp_helper_data = db.cfgdb.get_table('VLAN') vlan_ip_data = db.cfgdb.get_table('VLAN_INTERFACE') vlan_ports_data = db.cfgdb.get_table('VLAN_MEMBER') # Defining dictionaries for DHCP Helper address, Interface Gateway IP, # VLAN ports and port tagging vlan_dhcp_helper_dict = {} vlan_ip_dict = {} vlan_ports_dict = {} vlan_tagging_dict = {} vlan_proxy_arp_dict = {} # Parsing DHCP Helpers info for key in natsorted(list(vlan_dhcp_helper_data.keys())): try: if vlan_dhcp_helper_data[key]['dhcp_servers']: vlan_dhcp_helper_dict[key.strip( 'Vlan')] = vlan_dhcp_helper_data[key]['dhcp_servers'] except KeyError: vlan_dhcp_helper_dict[key.strip('Vlan')] = " " # Parsing VLAN Gateway info for key in vlan_ip_data: if clicommon.is_ip_prefix_in_key(key): interface_key = key[0].strip("Vlan") interface_value = key[1] if interface_key in vlan_ip_dict: vlan_ip_dict[interface_key].append(interface_value) else: vlan_ip_dict[interface_key] = [interface_value] else: interface_key = key.strip("Vlan") if 'proxy_arp' in vlan_ip_data[key]: proxy_arp_status = vlan_ip_data[key]['proxy_arp'] else: proxy_arp_status = "disabled" vlan_proxy_arp_dict[interface_key] = proxy_arp_status iface_alias_converter = clicommon.InterfaceAliasConverter(db) # Parsing VLAN Ports info for key in natsorted(list(vlan_ports_data.keys())): ports_key = key[0].strip("Vlan") ports_value = key[1] ports_tagging = vlan_ports_data[key]['tagging_mode'] if ports_key in vlan_ports_dict: if clicommon.get_interface_naming_mode() == "alias": ports_value = iface_alias_converter.name_to_alias(ports_value) vlan_ports_dict[ports_key].append(ports_value) else: if clicommon.get_interface_naming_mode() == "alias": ports_value = iface_alias_converter.name_to_alias(ports_value) vlan_ports_dict[ports_key] = [ports_value] if ports_key in vlan_tagging_dict: vlan_tagging_dict[ports_key].append(ports_tagging) else: vlan_tagging_dict[ports_key] = [ports_tagging] # Printing the following dictionaries in tablular forms: # vlan_dhcp_helper_dict={}, vlan_ip_dict = {}, vlan_ports_dict = {} # vlan_tagging_dict = {} for key in natsorted(list(vlan_dhcp_helper_dict.keys())): if key not in vlan_ip_dict: ip_address = "" else: ip_address = ','.replace(',', '\n').join(vlan_ip_dict[key]) if key not in vlan_ports_dict: vlan_ports = "" else: vlan_ports = ','.replace(',', '\n').join((vlan_ports_dict[key])) if key not in vlan_dhcp_helper_dict: dhcp_helpers = "" else: dhcp_helpers = ','.replace(',', '\n').join(vlan_dhcp_helper_dict[key]) if key not in vlan_tagging_dict: vlan_tagging = "" else: vlan_tagging = ','.replace(',', '\n').join( (vlan_tagging_dict[key])) vlan_proxy_arp = vlan_proxy_arp_dict.get(key, "disabled") body.append([ key, ip_address, vlan_ports, vlan_tagging, dhcp_helpers, vlan_proxy_arp ]) click.echo(tabulate(body, header, tablefmt="grid"))
def add_vlan_member_range(db, vid1, vid2, interface_name, untagged, warning): vlan_range_validate(vid1, vid2) ctx = click.get_current_context() if clicommon.get_interface_naming_mode() == "alias": interface_name = interface_alias_to_name(interface_name) if interface_name is None: ctx.fail("'interface_name' is None!") if interface_name_is_valid(db.cfgdb, interface_name) is False: ctx.fail("Interface name is invalid!!") vid2 = vid2 + 1 vlan_count = vid2 - vid1 if untagged is True and (vlan_count >= 2): ctx.fail( "Same interface {} cannot be untagged member of more than one VLAN" .format(interface_name)) warning_vlans_list = [] warning_membership_list = [] clients = db.cfgdb.get_redis_client(db.cfgdb.CONFIG_DB) pipe = clients.pipeline() for k, v in db.cfgdb.get_table('PORTCHANNEL_MEMBER'): if v == interface_name: ctx.fail(" {} is configured as a port channel member".format( interface_name)) for vid in range(vid1, vid2): vlan_name = 'Vlan{}'.format(vid) vlan = db.cfgdb.get_entry('VLAN', vlan_name) if len(vlan) == 0: if warning is True: warning_vlans_list.append(vid) continue members = vlan.get('members', []) if interface_name in members: if warning is True: warning_membership_list.append(vid) if clicommon.get_interface_naming_mode() == "alias": interface_name = interface_name_to_alias(interface_name) if interface_name is None: ctx.fail("'interface_name' is None!") continue else: continue members.append(interface_name) vlan['members'] = members pipe.hmset('VLAN|{}'.format(vlan_name), vlan_member_data(vlan)) pipe.hmset('VLAN_MEMBER|{}'.format(vlan_name + '|' + interface_name), {'tagging_mode': "untagged" if untagged else "tagged"}) # If port is being made L2 port, enable STP pipe.execute() # Log warning messages if 'warning' option is enabled if warning is True and len(warning_vlans_list) != 0: logging.warning('Non-existent VLANs: {}'.format( get_hyphenated_string(warning_vlans_list))) if warning is True and len(warning_membership_list) != 0: if (len(warning_membership_list) == 1): vlan_string = 'Vlan: ' else: vlan_string = 'Vlans: ' warning_string = str( interface_name ) + ' is already a member of ' + vlan_string + get_hyphenated_string( warning_membership_list) logging.warning('Membership exists already: {}'.format(warning_string))
def del_vlan_member_range(db, vid1, vid2, interface_name, warning): vlan_range_validate(vid1, vid2) ctx = click.get_current_context() if clicommon.get_interface_naming_mode() == "alias": interface_name = interface_alias_to_name(interface_name) if interface_name is None: ctx.fail("'interface_name' is None!") if interface_name_is_valid(db.cfgdb, interface_name) is False: ctx.fail("Interface name is invalid!!") vid2 = vid2 + 1 warning_vlans_list = [] warning_membership_list = [] clients = db.cfgdb.get_redis_client(db.cfgdb.CONFIG_DB) pipe = clients.pipeline() for vid in range(vid1, vid2): vlan_name = 'Vlan{}'.format(vid) vlan = db.cfgdb.get_entry('VLAN', vlan_name) if len(vlan) == 0: if warning is True: warning_vlans_list.append(vid) continue members = vlan.get('members', []) if interface_name not in members: if warning is True: warning_membership_list.append(vid) if clicommon.get_interface_naming_mode() == "alias": interface_name = interface_name_to_alias(interface_name) if interface_name is None: ctx.fail("'interface_name' is None!") continue else: continue members.remove(interface_name) if len(members) == 0: pipe.hdel('VLAN|{}'.format(vlan_name), 'members@') else: vlan['members'] = members pipe.hmset('VLAN|{}'.format(vlan_name), vlan_member_data(vlan)) pipe.delete('VLAN_MEMBER|{}'.format(vlan_name + '|' + interface_name)) pipe.delete('STP_VLAN_INTF|{}'.format(vlan_name + '|' + interface_name)) pipe.execute() # Log warning messages if 'warning' option is enabled if warning is True and len(warning_vlans_list) != 0: logging.warning('Non-existent VLANs: {}'.format( get_hyphenated_string(warning_vlans_list))) if warning is True and len(warning_membership_list) != 0: if (len(warning_membership_list) == 1): vlan_string = 'Vlan: ' else: vlan_string = 'Vlans: ' warning_string = str( interface_name ) + ' is not a member of ' + vlan_string + get_hyphenated_string( warning_membership_list) logging.warning('Non-existent membership: {}'.format(warning_string))
def mpls(ctx, interfacename, namespace, display): """Show Interface MPLS status""" #Edge case: Force show frontend interfaces on single asic if not (multi_asic.is_multi_asic()): if (display == 'frontend' or display == 'all' or display is None): display = None else: print("Error: Invalid display option command for single asic") return display = "all" if interfacename else display masic = multi_asic_util.MultiAsic(display_option=display, namespace_option=namespace) ns_list = masic.get_ns_list_based_on_options() intfs_data = {} intf_found = False for ns in ns_list: appl_db = multi_asic.connect_to_all_dbs_for_ns(namespace=ns) if interfacename is not None: interfacename = try_convert_interfacename_from_alias( ctx, interfacename) # Fetching data from appl_db for intfs keys = appl_db.keys(appl_db.APPL_DB, "INTF_TABLE:*") for key in keys if keys else []: tokens = key.split(":") ifname = tokens[1] # Skip INTF_TABLE entries with address information if len(tokens) != 2: continue if (interfacename is not None): if (interfacename != ifname): continue intf_found = True if (display != "all"): if ("Loopback" in ifname): continue if ifname.startswith( "Ethernet") and multi_asic.is_port_internal( ifname, ns): continue if ifname.startswith( "PortChannel") and multi_asic.is_port_channel_internal( ifname, ns): continue mpls_intf = appl_db.get_all(appl_db.APPL_DB, key) if 'mpls' not in mpls_intf or mpls_intf['mpls'] == 'disable': intfs_data.update({ifname: 'disable'}) else: intfs_data.update({ifname: mpls_intf['mpls']}) # Check if interface is valid if (interfacename is not None and not intf_found): ctx.fail('interface {} doesn`t exist'.format(interfacename)) header = ['Interface', 'MPLS State'] body = [] # Output name and alias for all interfaces for intf_name in natsorted(list(intfs_data.keys())): if clicommon.get_interface_naming_mode() == "alias": alias = clicommon.InterfaceAliasConverter().name_to_alias( intf_name) body.append([alias, intfs_data[intf_name]]) else: body.append([intf_name, intfs_data[intf_name]]) click.echo(tabulate(body, header))