def voss_parse(lines, indent=None, comment_tokens=None): toplevel = re.compile(r'(^interface.*$)|(^router \w+$)|(^router vrf \w+$)') exitline = re.compile(r'^exit$') entry_reg = re.compile(r'([{};])') ancestors = list() config = list() dup_parent_index = None for line in to_native(lines, errors='surrogate_or_strict').split('\n'): text = entry_reg.sub('', line).strip() cfg = ConfigLine(text) if not text or ignore_line(text, comment_tokens): continue # Handle top level commands if toplevel.match(text): # Looking to see if we have existing parent for index, item in enumerate(config): if item.text == text: # This means we have an existing parent with same label dup_parent_index = index break ancestors = [cfg] config.append(cfg) # Handle 'exit' line elif exitline.match(text): ancestors = list() if dup_parent_index is not None: # We're working with a duplicate parent # Don't need to store exit, just go to next line in config dup_parent_index = None else: cfg._parents = ancestors[:1] config.append(cfg) # Handle sub-level commands. Only have single sub-level elif ancestors: cfg._parents = ancestors[:1] if dup_parent_index is not None: # Update existing entry, since this already exists in config config[int(dup_parent_index)].add_child(cfg) new_index = dup_parent_index + 1 config.insert(new_index, cfg) else: ancestors[0].add_child(cfg) config.append(cfg) else: # Global command, no further special handling needed config.append(cfg) return config
def add(self, lines, parents=None, duplicates=False): ancestors = list() offset = 0 obj = None # global config command if not parents: for line in lines: # handle ignore lines if ignore_line(line): continue item = ConfigLine(line) item.raw = line if item not in self.items: self.items.append(item) else: for index, p in enumerate(parents): try: i = index + 1 obj = self.get_block(parents[:i])[0] ancestors.append(obj) except ValueError: # add parent to config offset = index * self._indent obj = ConfigLine(p) obj.raw = p.rjust(len(p) + offset) if ancestors: obj._parents = list(ancestors) ancestors[-1]._children.append(obj) self.items.append(obj) ancestors.append(obj) # add child objects for line in lines: # handle ignore lines if ignore_line(line): continue # check if child already exists for child in ancestors[-1]._children: if child.text == line and not duplicates: break else: offset = len(parents) * self._indent item = ConfigLine(line) item.raw = line.rjust(len(line) + offset) item._parents = ancestors ancestors[-1]._children.append(item) self.items.append(item)
def os6_parse(lines, indent=None, comment_tokens=None): sublevel_cmds = [ re.compile(r'^vlan !(priority).*$'), re.compile(r'^stack.*$'), re.compile(r'^interface.*$'), re.compile(r'datacenter-bridging.*$'), re.compile(r'line (console|telnet|ssh).*$'), re.compile(r'ip ssh !(server).*$'), re.compile(r'ip dhcp pool.*$'), re.compile(r'ip vrf !(forwarding).*$'), re.compile(r'(ip|mac|management|arp) access-list.*$'), re.compile(r'ipv6 (dhcp pool|router).*$'), re.compile(r'mail-server.*$'), re.compile(r'vpc domain.*$'), re.compile(r'router.*$'), re.compile(r'route-map.*$'), re.compile(r'policy-map.*$'), re.compile(r'class-map match-all.*$'), re.compile(r'captive-portal.*$'), re.compile(r'admin-profile.*$'), re.compile(r'link-dependency group.*$'), re.compile(r'banner motd.*$'), re.compile(r'openflow.*$'), re.compile(r'support-assist.*$'), re.compile(r'template.*$'), re.compile(r'address-family.*$'), re.compile(r'spanning-tree mst configuration.*$'), re.compile( r'logging (?!.*(cli-command|buffered|console|email|facility|file|monitor|protocol|snmp|source-interface|traps|web-session)).*$' ), re.compile(r'(radius-server|tacacs-server) host.*$') ] childline = re.compile(r'^exit$') config = list() parent = list() children = [] parent_match = False for line in str(lines).split('\n'): text = str(re.sub(r'([{};])', '', line)).strip() cfg = ConfigLine(text) cfg.raw = line if not text or ignore_line(text, comment_tokens): parent = list() children = [] continue else: parent_match = False # handle sublevel parent for pr in sublevel_cmds: if pr.match(line): if len(parent) != 0: cfg._parents.extend(parent) parent.append(cfg) config.append(cfg) if children: children.insert(len(parent) - 1, []) children[len(parent) - 2].append(cfg) parent_match = True continue # handle exit if childline.match(line): if children: parent[len(children) - 1]._children.extend( children[len(children) - 1]) if len(children) > 1: parent[len(children) - 2]._children.extend( parent[len(children) - 1]._children) cfg._parents.extend(parent) children.pop() parent.pop() if not children: children = list() if parent: cfg._parents.extend(parent) parent = list() config.append(cfg) # handle sublevel children elif parent_match is False and len(parent) > 0: if not children: cfglist = [cfg] children.append(cfglist) else: children[len(parent) - 1].append(cfg) cfg._parents.extend(parent) config.append(cfg) # handle global commands elif not parent: config.append(cfg) return config
def fos_parse(lines, indent=None, comment_tokens=None): sublevel_cmds = [ re.compile(r'^interface.*$'), re.compile(r'line (console|ssh|vty).*$'), re.compile(r'ip vrf.*$'), re.compile(r'(ip|mac|arp) access-list.*$'), re.compile(r'ipv6 router.*$'), re.compile(r'data-center-bridging.*$'), re.compile(r'router.*$'), re.compile(r'route-map.*$'), re.compile(r'policy-map.*$'), re.compile(r'class-map.*$'), re.compile(r'openflow.*$'), re.compile(r'hybridmode (per-port|per-vlan).*$') ] vlanDbLine = re.compile(r'vlan database$') vlanLstLine = re.compile(r'vlan \d+([,|-]\d+)?$') childline = re.compile(r'^exit$') config = list() parent = list() children = [] countexit = 0 inVlanDbMode = False parent_match = False for line in str(lines).split('\n'): text = str(re.sub(r'([{};])', '', line)).strip() cfg = ConfigLine(text) cfg.raw = line if not text or ignore_line(text, comment_tokens): parent = list() children = [] continue else: parent_match = False if vlanDbLine.match(line): inVlanDbMode = True parent_match = True elif not inVlanDbMode: if vlanLstLine.match(line): parent_match = True # handle sublevel parent if not parent_match: for pr in sublevel_cmds: if pr.match(line): parent_match = True break if parent_match: if len(parent) != 0: cfg._parents.extend(parent) parent.append(cfg) config.append(cfg) if children: children.insert(len(parent) - 1, []) children[len(parent) - 2].append(cfg) # handle exit if childline.match(line): inVlanDbMode = False countexit += 1 if children: parent[len(children) - 1]._children.extend( children[len(children) - 1]) if len(children) > 1: parent[len(children) - 2]._children.extend( parent[len(children) - 1]._children) cfg._parents.extend(parent) children.pop() parent.pop() if not children: children = list() if parent: cfg._parents.extend(parent) parent = list() config.append(cfg) # handle sublevel children elif parent_match is False and len(parent) > 0: if not children: cfglist = [cfg] children.append(cfglist) else: children[len(parent) - 1].append(cfg) cfg._parents.extend(parent) config.append(cfg) # handle global commands elif not parent: config.append(cfg) return config
def os6_parse(lines, indent=None, comment_tokens=None): sublevel_cmds = [ re.compile(r'^vlan.*$'), re.compile(r'^stack.*$'), re.compile(r'^interface.*$'), re.compile(r'datacenter-bridging.*$'), re.compile(r'line (console|telnet|ssh).*$'), re.compile(r'ip ssh !(server).*$'), re.compile(r'ip (dhcp|vrf).*$'), re.compile(r'(ip|mac|management|arp) access-list.*$'), re.compile(r'ipv6 (dhcp|router).*$'), re.compile(r'mail-server.*$'), re.compile(r'vpc domain.*$'), re.compile(r'router.*$'), re.compile(r'route-map.*$'), re.compile(r'policy-map.*$'), re.compile(r'class-map match-all.*$'), re.compile(r'captive-portal.*$'), re.compile(r'admin-profile.*$'), re.compile(r'link-dependency group.*$'), re.compile(r'banner motd.*$'), re.compile(r'openflow.*$'), re.compile(r'support-assist.*$'), re.compile(r'template.*$'), re.compile(r'address-family.*$'), re.compile(r'spanning-tree mst configuration.*$'), re.compile(r'logging.*$'), re.compile(r'(radius-server|tacacs-server) host.*$')] childline = re.compile(r'^exit$') config = list() parent = list() children = [] parent_match = False for line in str(lines).split('\n'): text = str(re.sub(r'([{};])', '', line)).strip() cfg = ConfigLine(text) cfg.raw = line if not text or ignore_line(text, comment_tokens): parent = list() children = [] continue else: parent_match = False # handle sublevel parent for pr in sublevel_cmds: if pr.match(line): if len(parent) != 0: cfg._parents.extend(parent) parent.append(cfg) config.append(cfg) if children: children.insert(len(parent) - 1, []) children[len(parent) - 2].append(cfg) parent_match = True continue # handle exit if childline.match(line): if children: parent[len(children) - 1]._children.extend(children[len(children) - 1]) if len(children) > 1: parent[len(children) - 2]._children.extend(parent[len(children) - 1]._children) cfg._parents.extend(parent) children.pop() parent.pop() if not children: children = list() if parent: cfg._parents.extend(parent) parent = list() config.append(cfg) # handle sublevel children elif parent_match is False and len(parent) > 0: if not children: cfglist = [cfg] children.append(cfglist) else: children[len(parent) - 1].append(cfg) cfg._parents.extend(parent) config.append(cfg) # handle global commands elif not parent: config.append(cfg) return config