def get_vlans(self): vlan_list = self.ssh.do("show vlan brief") vlans = {} for line in vlan_list: if regex.match('^(\d+)\s+(\S+).*', line): number, name = regex if name == ("VLAN{}".format(number)): name = None vlans[number] = Vlan(int(number), name, icmp_redirects=True, arp_routing=True, ntp=True) for ip_interface_data in split_on_dedent( self.ssh.do("show ip interface")): if regex.match("^Vlan(\d+)\s.*", ip_interface_data[0]): current_vlan = vlans.get(regex[0]) if current_vlan: apply_interface_running_config_data( current_vlan, self.ssh.do( "show running-config interface vlan {}".format( current_vlan.number))) return vlans.values()
def resolve_port_mode(interface_data): for line in interface_data: if regex.match("switchport mode (\S+)", line): return regex[0] elif regex.match("switchport access vlan .*", line): return "access" return None
def get_vlan(self, number): result = self.shell.do("show vlan id {}".format(number)) if regex.match(".*\^.*", result[0]): raise BadVlanNumber elif regex.match("^ERROR", result[0]): raise UnknownVlan else: return parse_vlan_list(result)[0]
def get_vlan(self, number): result = self.shell.do("show vlan id {}".format(number)) if regex.match(".*\^.*", result[0]): raise BadVlanNumber() elif regex.match("^ERROR", result[0]): raise UnknownVlan(number) else: return parse_vlan_list(result)[0]
def parse_interface(if_data): if regex.match("^\w*Ethernet([^\s]*) is (\w*).*", if_data[0]): i = Interface(name="ethernet {}".format(regex[0]), port_mode=ACCESS, shutdown=regex[1] == "disabled") for line in if_data: if regex.match("Port name is (.*)", line): i.description = regex[0] return i
def parse_interface_names(status_list): interfaces = [] for line in status_list: if regex.match("Te(\d+/\d+/\S+).*", line): interfaces.append("tengigabitethernet {}".format(regex[0])) elif regex.match("Po(\d+).*", line): interfaces.append("port-channel {}".format(regex[0])) return interfaces
def get_vlan(self, vlan_number): result = self.page_reader.do(self.shell, "show vlan id {}".format(vlan_number)) if regex.match(".*\^.*", result[0]): raise BadVlanNumber() elif regex.match("^ERROR", result[0]): raise UnknownVlan(vlan_number) vlan = parse_vlan_list(result)[0] return vlan
def parse_interface_names(self, status_list): interfaces = [] for line in status_list: if regex.match("(\d\S+).*", line): interfaces.append("ethernet {}".format(regex[0])) elif regex.match("ch(\d+).*", line): interfaces.append("port-channel {}".format(regex[0])) return interfaces
def get_vlan_interfaces(self, vlan_number): result = self.shell.do("show vlan id {}".format(vlan_number)) if regex.match(".*\^.*", result[0]): raise BadVlanNumber() elif regex.match("^ERROR", result[0]): raise UnknownVlan(vlan_number) return self.parse_interface_from_vlan_list(vlan_number, result)
def get_vlan_interfaces(self, vlan_number): result = self.shell.do("show vlan id {}".format(vlan_number), wait_for=("--More-- or (q)uit", "#"), include_last_line=True) while len(result) > 0 and "--More--" in result[-1]: result += self.shell.send_key("m", wait_for=("--More-- or (q)uit", "#"), include_last_line=True) if regex.match(".*\^.*", result[0]): raise BadVlanNumber() elif regex.match("^ERROR", result[0]): raise UnknownVlan(vlan_number) return self.parse_interface_from_vlan_list(vlan_number, result)
def parse_vlan_list(result): vlans = [] for line in result: if regex.match('^(\d+)\s{1,6}(\S+).*', line): number, name = regex vlans.append(Vlan(number=int(number), name=name if int(number) > 1 else "default")) elif regex.match('^(\d+)\s+.*', line): number = regex[0] vlans.append(Vlan(number=int(number))) return vlans
def parse_vlan_list(result): vlans = [] for line in result: if regex.match("^(\d+)(.*)", line): number, leftovers = regex name = None if regex.match("^\s{1,6}(\S+).*", leftovers): name = regex[0] vlan = Vlan(number=int(number), name=name if int(number) > 1 else "default") vlans.append(vlan) return vlans
def test_should_be_threadsafe(self): regex.match('^(\w+)\s(\w+)$', 'hello world') def match_single_word(): regex.match('^(\w+)$', 'bonjour') assert_that(regex[0], is_('bonjour')) t = Thread(target=match_single_word) t.start() t.join() assert_that(regex[1], is_('world'))
def parse_vlan_runningconfig(data): vlan = {"tagged_interface": [], "untagged_interface": []} if regex.match("^vlan (\d*)", data[0]): vlan['id'] = int(regex[0]) for line in data: if regex.match(" untagged (.*)", line): for name in _to_real_names(parse_if_ranges(regex[0])): vlan["untagged_interface"].append(name) if regex.match(" tagged (.*)", line): for name in _to_real_names(parse_if_ranges(regex[0])): vlan["tagged_interface"].append(name) return vlan
def parse_vlan_list(result): vlans = [] for line in result: if regex.match('^(\d+)(.*)', line): number, leftovers = regex name = None if regex.match('^\s{1,6}(\S+).*', leftovers): name = regex[0] vlan = Vlan(number=int(number), name=name if int(number) > 1 else "default") vlans.append(vlan) return vlans
def parse_vlan_list(result): vlans = [] for line in result: if regex.match("^(\d+)\s{1,6}(\S+).*", line): number, name = regex if name == "VLAN{:0>4}".format(number): name = None vlans.append(Vlan(number=int(number), name=name if int(number) > 1 else "default")) elif regex.match("^(\d+)\s+.*", line): number = regex[0] vlans.append(Vlan(number=int(number))) return vlans
def add_vlan(self, number, name=None): result = self.shell.do("show vlan id {}".format(number)) if regex.match(".*\^.*", result[0]): raise BadVlanNumber() elif regex.match("^VLAN", result[0]): raise VlanAlreadyExist(number) with self.config(): with self.vlan_database(): self.set('vlan {}', number) if name is not None: with self.interface("vlan {}".format(number)): self.set('name {}', name).on_any_result(BadVlanName)
def parse_vlan(vlan_data): regex.match("^vlan (\d+).*", vlan_data[0]) current_vlan = VlanBrocade(int(regex[0])) if regex.match("^vlan \d+ name ([^\s]*)", vlan_data[0]): current_vlan.name = regex[0] if regex[0] != "DEFAULT-VLAN" else "default" else: current_vlan.name = None for line in vlan_data[1:]: if regex.match("^\srouter-interface ve (\d+)", line): current_vlan.vlan_interface_name = regex[0] return current_vlan
def parse_interface_from_vlan_list(self, vlan_number, result): vlan_interfaces = [] number = None for line in result: if regex.match('^(\d+)(.*)', line): number, leftover = regex if int(number) == vlan_number: if regex.match('^\s{1,6}\S*\s+([a-zA-Z0-9-,/]+).*', leftover): vlan_interfaces.extend(self.parse_interface_port_list(regex[0])) elif regex.match('^\s+([a-zA-Z0-9-,/]+).*', line) and int(number) == vlan_number: vlan_interfaces.extend(self.parse_interface_port_list(regex[0])) return vlan_interfaces
def _get_vlan(self, vlan_number, include_vif_data=False): result = self._show_vlan(vlan_number) if result[0].startswith("Error"): raise UnknownVlan(vlan_number) vlan = VlanBrocade(vlan_number) for line in result: if regex.match(".*PORT-VLAN \d*, Name ([^,]+),.*", line): vlan.name = regex[0] if regex[0] != "[None]" else None vlan.name = vlan.name if vlan.name != "DEFAULT-VLAN" else "default" elif regex.match(".*Associated Virtual Interface Id: (\d+).*", line): vlan.vlan_interface_name = regex[0] if include_vif_data: add_interface_vlan_data(vlan, self.shell.do("show running-config interface ve {}".format(regex[0]))) return vlan
def parse_if_ranges(string): consumed_string = string.strip() while len(consumed_string) > 0: if regex.match("^(([^\s]*) ([^\s]*) to ([^\s]*)).*", consumed_string): parsed_part, port_type, lower_bound, higher_bound = regex lower_values = lower_bound.split("/") higher_values = higher_bound.split("/") for port_id in range(int(lower_values[-1]), int(higher_values[-1]) + 1): yield "{} {}/{}".format(port_type, "/".join(lower_values[:-1]), port_id) else: regex.match("^([^\s]* [^\s]*).*", consumed_string) parsed_part = regex[0] yield regex[0] consumed_string = consumed_string[len(parsed_part):].strip()
def parse_vlan_list(result): vlans = [] for line in result: if regex.match("^(\d+)(.*)", line): number, leftovers = regex name = None if regex.match("^\s{1,6}(\S+)\s+([A-Za-z0-9-,/]+)", leftovers): name, ports = regex elif regex.match("^\s{1,6}(\S+).*", leftovers): name = regex[0] if name == "VLAN{:0>4}".format(number): name = None vlan = Vlan(number=int(number), name=name if int(number) > 1 else "default") vlans.append(vlan) return vlans
def get_interface_data(self, interface_id): interface_data = self.shell.do( "show running-config interface {}".format(interface_id)) if len(interface_data) > 0 and regex.match(".*invalid interface.*", interface_data[0]): raise UnknownInterface(interface_id) return interface_data
def read_interface(self, interface_name): data = self.get_interface_data(interface_name) interface = Interface(name=interface_name, port_mode=ACCESS, shutdown=False) for line in data: if regex.match("switchport mode \S+", line): interface.port_mode = TRUNK if regex.match("shutdown", line): interface.shutdown = True if regex.match("switchport access vlan (\d+)", line): interface.access_vlan = int(regex[0]) if regex.match("switchport general pvid (\d+)", line): interface.trunk_native_vlan = int(regex[0]) if regex.match("switchport \S* allowed vlan (add )?(\S+)", line): interface.trunk_vlans = parse_vlan_ranges(regex[1]) return interface
def add_vif_data_to_vlans(self, vlans): vlans_interface_name_dict = {vlan.vlan_interface_name: vlan for vlan in vlans if vlan.vlan_interface_name} for int_vlan_data in split_on_bang(self.shell.do("show running-config interface")): if regex.match("^interface ve (\d+)", int_vlan_data[0]): current_vlan = vlans_interface_name_dict.get(regex[0]) if current_vlan: add_interface_vlan_data(current_vlan, int_vlan_data)
def _get_vlan_association_removal_operations(self, result): operations = [] for line in result: if regex.match("VLAN: (\d*) ([^\s]*)", line): vlan, state = regex if int(vlan) > 1: operations.append((vlan, state.lower())) return operations
def parse_vlan(vlan_data): regex.match("^vlan (\d+).*", vlan_data[0]) current_vlan = VlanBrocade(int(regex[0])) if regex.match("^vlan \d+ name ([^\s]*)", vlan_data[0]): current_vlan.name = regex[0] if regex[0] != "DEFAULT-VLAN" else "default" else: current_vlan.name = None for line in vlan_data[1:]: if regex.match("^\srouter-interface ve (\d+)", line): current_vlan.vlan_interface_name = regex[0] elif regex.match(" tagged (.*)", line): for name in parse_if_ranges(regex[0]): current_vlan.tagged_interfaces.append(name) return current_vlan
def parse_vlan_list(result): vlans = [] for line in result: if regex.match('^(\d+)(.*)', line): number, leftovers = regex name = None if regex.match('^\s{1,6}(\S+)\s+([A-Za-z0-9-,/]+)', leftovers): name, ports = regex elif regex.match('^\s{1,6}(\S+).*', leftovers): name = regex[0] if name == "VLAN{:0>4}".format(number): name = None vlan = Vlan(number=int(number), name=name if int(number) > 1 else "default") vlans.append(vlan) return vlans
def parse_interface(data): if data and (regex.match("interface (\w*Ethernet[^\s]*)", data[0]) or regex.match("interface (Port-channel[^\s]*)", data[0])): i = Interface(name=regex[0], shutdown=False) port_mode = access_vlan = native_vlan = trunk_vlans = None for line in data: if regex.match(" switchport mode (.*)", line): port_mode = regex[0] if regex.match(" switchport access vlan (\d*)", line): access_vlan = int(regex[0]) if regex.match(" switchport trunk native vlan (\d*)", line): native_vlan = int(regex[0]) if regex.match(" switchport trunk allowed vlan (.*)", line): trunk_vlans = regex[0] if regex.match(" shutdown", line): i.shutdown = True if not port_mode: i.port_mode = DYNAMIC i.access_vlan = access_vlan i.trunk_native_vlan = native_vlan i.trunk_vlans = parse_vlan_ranges( trunk_vlans) if trunk_vlans else [] elif port_mode == 'access': i.port_mode = ACCESS i.access_vlan = access_vlan elif port_mode == 'trunk': i.port_mode = TRUNK i.trunk_native_vlan = native_vlan i.trunk_vlans = parse_vlan_ranges( trunk_vlans) if trunk_vlans else [] return i return None
def parse_interface(data): if data and (regex.match("interface (\w*Ethernet[^\s]*)", data[0]) or regex.match("interface (Port-channel[^\s]*)", data[0])): i = Interface(name=regex[0], shutdown=False) port_mode = access_vlan = native_vlan = trunk_vlans = None for line in data: if regex.match(" switchport mode (.*)", line): port_mode = regex[0] if regex.match(" switchport access vlan (\d*)", line): access_vlan = int(regex[0]) if regex.match(" switchport trunk native vlan (\d*)", line): native_vlan = int(regex[0]) if regex.match(" switchport trunk allowed vlan (.*)", line): trunk_vlans = regex[0] if regex.match(" shutdown", line): i.shutdown = True if not port_mode: i.port_mode = DYNAMIC i.access_vlan = access_vlan i.trunk_native_vlan = native_vlan i.trunk_vlans = parse_vlan_ranges(trunk_vlans) if trunk_vlans else [] elif port_mode == 'access': i.port_mode = ACCESS i.access_vlan = access_vlan elif port_mode == 'trunk': i.port_mode = TRUNK i.trunk_native_vlan = native_vlan i.trunk_vlans = parse_vlan_ranges(trunk_vlans) if trunk_vlans else [] return i return None
def apply_interface_running_config_data(vlan, data): for line in data: if regex.match("^ ip address ([^\s]*) ([^\s]*)(.*)", line): ip = IPNetwork("{}/{}".format(regex[0], regex[1])) if "secondary" not in regex[2]: vlan.ips.insert(0, ip) else: vlan.ips.append(ip) elif regex.match("^ ip access-group ([^\s]*) ([^\s]*).*", line): if regex[1] == "in": vlan.access_groups[IN] = regex[0] else: vlan.access_groups[OUT] = regex[0] elif regex.match("^ ip vrf forwarding ([^\s]*).*", line): vlan.vrf_forwarding = regex[0] elif regex.match("^ standby ([^\s]*)(.*)", line): vrrp_group = next( (group for group in vlan.vrrp_groups if str(group.id) == regex[0]), None) if vrrp_group is None: vrrp_group = VrrpGroup(id=int(regex[0])) vlan.vrrp_groups.append(vrrp_group) vrrp_info = regex[1].strip() if regex.match("^ip ([^\s]*).*", vrrp_info): vrrp_group.ips.append(IPAddress(regex[0])) elif regex.match("^timers ([^\s]*) ([^\s]*)", vrrp_info): vrrp_group.hello_interval = int(regex[0]) vrrp_group.dead_interval = int(regex[1]) elif regex.match("^priority ([^\s]*)", vrrp_info): vrrp_group.priority = int(regex[0]) elif regex.match("^track ([^\s]*) decrement ([^\s]*)", vrrp_info): vrrp_group.track_id = regex[0] vrrp_group.track_decrement = int(regex[1]) elif regex.match("^ ip helper-address ([^\s]*)", line): vlan.dhcp_relay_servers.append(IPAddress(regex[0])) elif regex.match("^ no ip redirects", line): vlan.icmp_redirects = False
def add_vlan(self, number, name=None): result = self.shell.do("show vlan id {}".format(number)) if regex.match(".*\^.*", result[0]): raise BadVlanNumber() elif regex.match("^VLAN", result[0]): raise VlanAlreadyExist(number) with self.config(): result = self.shell.do('vlan {}'.format(number)) if len(result) > 0: raise BadVlanNumber() else: if name: result = self.shell.do('name {}'.format(name)) self.shell.do('exit') if len(result) > 0: raise BadVlanName()
def _apply_interface_vlan_data(self, vlans): config = self._fetch_interface_vlans_config(vlans) for interface in split_on_dedent(config): if regex.match("^.*Vlan(\d+)$", interface[0]): vlan = _find_vlan_by_number(vlans, regex[0]) for line in interface[1:]: if regex.match(" *ip helper-address (.*)", line): try: vlan.dhcp_relay_servers.append(IPAddress(regex[0])) except AddrFormatError: self.logger.warning( 'Unsupported IP Helper address found in Vlan {} : {}'.format(vlan.number, regex[0])) if regex.match(" *ip virtual-router address (.*)", line): vlan.varp_ips.append(IPNetwork(regex[0])) if regex.match(" *load-interval (.*)", line): vlan.load_interval = int(regex[0]) if regex.match(" *no mpls ip", line): vlan.mpls_ip = False
def get_vlan_interfaces(self, vlan_number): interfaces = [] result = self._show_vlan(vlan_number) if result[0].startswith("Error"): raise UnknownVlan(vlan_number) for line in result: if regex.match("(Untagged|Statically tagged) Ports\s+: (.*)$", line): for real_name in _to_real_names(parse_if_ranges(regex[1])): interfaces.append(real_name) return interfaces
def get_interface_data(self, interface_id): interface_data = self.page_reader.do( self.shell, "show running-config interface {}".format(interface_id)) if any([ "Invalid input" in line or regex.match("ERROR.*", line) for line in interface_data ]): raise UnknownInterface(interface_id) return interface_data
def parse_interface_port_list(self, ports): port_list = filter(None, ports.split(',')) interface_list = [] for port in port_list: if regex.match('^ch(\d+)-(\d+)', port): start, end = regex for i in range(int(start), int(end)+1): interface_list.append("port-channel {}".format(i)) elif regex.match('^ch(\d+)', port): start = regex[0] interface_list.append("port-channel {}".format(start)) elif regex.match('^(\d/[a-z]+)(\d+)-\d/[a-z]+(\d+)', port): debut, start, end = regex for i in range(int(start), int(end)+1): interface_list.append("ethernet {0}{1}".format(debut, i)) elif regex.match('^(\d/[a-z]+)(\d+)', port): debut, start = regex interface_list.append("ethernet {0}{1}".format(debut, start)) return interface_list
def apply_interface_running_config_data(vlan, data): for line in data: if regex.match("^ ip address ([^\s]*) ([^\s]*)(.*)", line): ip = IPNetwork("{}/{}".format(regex[0], regex[1])) if "secondary" not in regex[2]: vlan.ips.insert(0, ip) else: vlan.ips.append(ip) elif regex.match("^ ip access-group ([^\s]*) ([^\s]*).*", line): if regex[1] == "in": vlan.access_groups[IN] = regex[0] else: vlan.access_groups[OUT] = regex[0] elif regex.match("^ ip vrf forwarding ([^\s]*).*", line): vlan.vrf_forwarding = regex[0] elif regex.match("^ standby ([^\s]*)(.*)", line): vrrp_group = next((group for group in vlan.vrrp_groups if str(group.id) == regex[0]), None) if vrrp_group is None: vrrp_group = VrrpGroup(id=int(regex[0])) vlan.vrrp_groups.append(vrrp_group) vrrp_info = regex[1].strip() if regex.match("^ip ([^\s]*).*", vrrp_info): vrrp_group.ips.append(IPAddress(regex[0])) elif regex.match("^timers ([^\s]*) ([^\s]*)", vrrp_info): vrrp_group.hello_interval = int(regex[0]) vrrp_group.dead_interval = int(regex[1]) elif regex.match("^priority ([^\s]*)", vrrp_info): vrrp_group.priority = int(regex[0]) elif regex.match("^track ([^\s]*) decrement ([^\s]*)", vrrp_info): vrrp_group.track_id = regex[0] vrrp_group.track_decrement = int(regex[1]) elif regex.match("^ ip helper-address ([^\s]*)", line): vlan.dhcp_relay_servers.append(IPAddress(regex[0])) elif regex.match("^ no ip redirects", line): vlan.icmp_redirects = False
def parse_interfaces(interfaces_data, switchports_data): interfaces = [] for interface_data in interfaces_data.values(): if regex.match("(\w*Ethernet[^\s]*)", interface_data["name"]) or \ regex.match("(Port-channel[^\s]*)", interface_data["name"]): interface = Interface(name=interface_data["name"], shutdown=False) if interface_data["lineProtocolStatus"] == "down": interface.shutdown = True interface.mtu = int(interface_data["mtu"]) interface.auto_negotiation = ON if interface_data["autoNegotiate"] == "on" else OFF if interface.name in switchports_data: patch_switchport(interface, switchports_data[interface.name]["switchportInfo"]) interfaces.append(interface) return interfaces
def _is_vlan_in_interface_members(vlan_number, vlan_name, members): for member_name in members: if regex.match("(\d+)-(\d+)", member_name): start, end = regex if int(start) <= vlan_number <= int(end): return True elif member_name == vlan_name: return True elif int(member_name) == vlan_number: return True return False
def parse_interface_port_list(self, ports): port_list = filter(None, ports.split(',')) interfaces = [] for line in port_list: if regex.match("Te(\d+/\d+/)(\d+)-(\d+).*", line): debut, start, end = regex for i in range(int(start), int(end)+1): interfaces.append("tengigabitethernet {0}{1}".format(debut, i)) elif regex.match("Te(\d+/\d+/\S+).*", line): interfaces.append("tengigabitethernet {}".format(regex[0])) elif regex.match("Fo(\d+/\d+/)(\d+)-(\d+).*", line): debut, start, end = regex for i in range(int(start), int(end)+1): interfaces.append("fortygigabitethernet {0}{1}".format(debut, i)) elif regex.match("Fo(\d+/\d+/\S+).*", line): interfaces.append("fortygigabitethernet {}".format(regex[0])) elif regex.match("Po(\d+)-(\d+)", line): start, end = regex for i in range(int(start), int(end)+1): interfaces.append("port-channel {}".format(i)) elif regex.match("Po(\d+).*", line): interfaces.append("port-channel {}".format(regex[0])) return interfaces
def get_vlans(self): vlan_list = self.ssh.do("show vlan brief") vlans = {} for line in vlan_list: if regex.match('^(\d+)\s+(\S+).*', line): number, name = regex if name == ("VLAN{}".format(number)): name = None vlans[number] = Vlan(int(number), name, icmp_redirects=True) for ip_interface_data in split_on_dedent(self.ssh.do("show ip interface")): if regex.match("^Vlan(\d+)\s.*", ip_interface_data[0]): current_vlan = vlans.get(regex[0]) if current_vlan: apply_interface_running_config_data( current_vlan, self.ssh.do("show running-config interface vlan {}".format(current_vlan.number)) ) return vlans.values()