Merge pull request #16423 from privateip/netcfg

bug fix in netcfg replace method to handle whitespace argument
This commit is contained in:
Peter Sprygada 2016-07-04 22:54:16 -04:00 committed by GitHub
commit 0430923647

View file

@ -19,7 +19,6 @@
import re import re
import time import time
import collections
import itertools import itertools
import shlex import shlex
import itertools import itertools
@ -133,12 +132,9 @@ class NetworkConfig(object):
return lines return lines
def __str__(self): def __str__(self):
text = '' if self._device_os == 'junos':
for item in self.items: return self.to_lines(self.expand(self.items))
if not item.parents: return self.to_block(self.expand(self.items))
expand = self.get_section(item.text)
text += '%s\n' % self.get_section(item.text)
return str(text).strip()
def load(self, contents): def load(self, contents):
self._config = parse(contents, indent=self.indent) self._config = parse(contents, indent=self.indent)
@ -180,18 +176,17 @@ class NetworkConfig(object):
regexp = r'%s' % regexp regexp = r'%s' % regexp
return re.findall(regexp, str(self)) return re.findall(regexp, str(self))
def expand(self, obj, items): def expand(self, objs):
block = [item.raw for item in obj.parents] visited = set()
block.append(obj.raw) expanded = list()
for o in objs:
current_level = items for p in o.parents:
for b in block: if p not in visited:
if b not in current_level: visited.add(p)
current_level[b] = collections.OrderedDict() expanded.append(p)
current_level = current_level[b] expanded.append(o)
for c in obj.children: visited.add(o)
if c.raw not in current_level: return expanded
current_level[c.raw] = collections.OrderedDict()
def to_lines(self, section): def to_lines(self, section):
lines = list() lines = list()
@ -232,14 +227,6 @@ class NetworkConfig(object):
self.expand_section(child, S) self.expand_section(child, S)
return S return S
def flatten(self, data, obj=None):
if obj is None:
obj = list()
for k, v in data.items():
obj.append(k)
self.flatten(v, obj)
return obj
def get_object(self, path): def get_object(self, path):
for item in self.items: for item in self.items:
if item.text == path[-1]: if item.text == path[-1]:
@ -294,43 +281,47 @@ class NetworkConfig(object):
if self._device_os == 'junos': if self._device_os == 'junos':
return updates return updates
diffs = collections.OrderedDict() changes = list()
for update in updates: for update in updates:
if replace == 'block' and update.parents: if replace == 'block':
update = update.parents[-1] if update.parents:
self.expand(update, diffs) changes.append(update.parents[-1])
for child in update.parents[-1].children:
changes.append(child)
else:
changes.append(update)
else:
changes.append(update)
updates = self.expand(changes)
return self.flatten(diffs) return [item.text for item in updates]
def replace(self, patterns, repl, parents=None, add_if_missing=False,
ignore_whitespace=True):
def replace(self, replace, text=None, regex=None, parents=None,
add_if_missing=False, ignore_whitespace=False):
match = None match = None
parents = parents or list() parents = to_list(parents) or list()
if text is None and regex is None: patterns = [re.compile(r, re.I) for r in to_list(patterns)]
raise ValueError('missing required arguments')
if not regex:
regex = ['^%s$' % text]
patterns = [re.compile(r, re.I) for r in to_list(regex)]
for item in self.items: for item in self.items:
for regexp in patterns: for regexp in patterns:
string = ignore_whitespace is True and item.text or item.raw text = item.text
if regexp.search(item.text): if not ignore_whitespace:
if item.text != replace: text = item.raw
if regexp.search(text):
if item.text != repl:
if parents == [p.text for p in item.parents]: if parents == [p.text for p in item.parents]:
match = item match = item
break break
if match: if match:
match.text = replace match.text = repl
indent = len(match.raw) - len(match.raw.lstrip()) indent = len(match.raw) - len(match.raw.lstrip())
match.raw = replace.rjust(len(replace) + indent) match.raw = repl.rjust(len(repl) + indent)
elif add_if_missing: elif add_if_missing:
self.add(replace, parents=parents) self.add(repl, parents=parents)
def add(self, lines, parents=None): def add(self, lines, parents=None):