From 37524b798d8a2406723ec1d799dbe9d056f37aaa Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Wed, 16 Aug 2017 08:59:14 -0400 Subject: [PATCH] updates network parse_cli filter to handle blocks from output (#28245) * updates network parse_cli filter to handle blocks from output * minor updates to finish up parse_cli filter * all vars are now under the vars key * attributes key has been changed to keys * added the start_block and end_block directives * update PEP8 failures --- lib/ansible/plugins/filter/network.py | 71 +++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/lib/ansible/plugins/filter/network.py b/lib/ansible/plugins/filter/network.py index f6a1a3f78a5..98dae86c609 100644 --- a/lib/ansible/plugins/filter/network.py +++ b/lib/ansible/plugins/filter/network.py @@ -81,13 +81,76 @@ def parse_cli(output, tmpl): spec = yaml.load(open(tmpl).read()) obj = {} - for name, attrs in iteritems(spec['attributes']): + for name, attrs in iteritems(spec['keys']): value = attrs['value'] if template.can_template(value): - value = template(value, spec) - - if 'items' in attrs: + variables = spec.get('vars', {}) + value = template(value, variables) + + if 'start_block' in attrs and 'end_block' in attrs: + start_block = re.compile(attrs['start_block']) + end_block = re.compile(attrs['end_block']) + + blocks = list() + lines = None + block_started = False + + for line in output.split('\n'): + match_start = start_block.match(line) + match_end = end_block.match(line) + + if match_start: + if lines: + blocks.append('\n'.join(lines)) + lines = list() + lines.append(line) + block_started = True + + elif match_end: + if lines: + lines.append(line) + block_started = False + + elif block_started: + if lines: + lines.append(line) + + regex_items = [re.compile(r) for r in attrs['items']] + objects = list() + + for block in blocks: + if isinstance(value, Mapping) and 'key' not in value: + items = list() + for regex in regex_items: + match = regex.search(block) + if match: + item_values = match.groupdict() + item_values['match'] = list(match.groups()) + items.append(item_values) + else: + items.append(None) + + objects.append(dict([(k, template(v, {'item': items})) for k, v in iteritems(value)])) + + elif isinstance(value, Mapping): + items = list() + for regex in regex_items: + match = regex.search(block) + if match: + item_values = match.groupdict() + item_values['match'] = list(match.groups()) + items.append(item_values) + else: + items.append(None) + + key = template(value['key'], {'item': items}) + values = dict([(k, template(v, {'item': items})) for k, v in iteritems(value['values'])]) + objects.append({key: values}) + + return objects + + elif 'items' in attrs: regexp = re.compile(attrs['items']) when = attrs.get('when') conditional = "{%% if %s %%}True{%% else %%}False{%% endif %%}" % when