From 6a223d55760dd21b5063ca2c8296f3ef57dd75e7 Mon Sep 17 00:00:00 2001 From: Ganesh Nalawade Date: Mon, 12 Feb 2018 12:33:22 +0530 Subject: [PATCH] Fix vrf parsing in eos_vrf and eos_eapi module (#35791) * Fix vrf parsing in eos_vrf and eos_eapi module Fixes #30250 Fix logic to parse vrf when interface value in `show vrf` command output spans on multiple lines * Add idempotent test case --- lib/ansible/modules/network/eos/eos_eapi.py | 10 ++- lib/ansible/modules/network/eos/eos_vrf.py | 32 +++++-- .../targets/eos_vrf/tests/cli/basic.yaml | 87 +++++++++++++++---- 3 files changed, 103 insertions(+), 26 deletions(-) diff --git a/lib/ansible/modules/network/eos/eos_eapi.py b/lib/ansible/modules/network/eos/eos_eapi.py index 7298a463ab0..1ad7e853a78 100644 --- a/lib/ansible/modules/network/eos/eos_eapi.py +++ b/lib/ansible/modules/network/eos/eos_eapi.py @@ -213,7 +213,15 @@ def validate_local_http_port(value, module): def validate_vrf(value, module): out = run_commands(module, ['show vrf']) - configured_vrfs = re.findall(r'^\s+(\w+)(?=\s)', out[0], re.M) + configured_vrfs = [] + lines = out[0].strip().splitlines()[3:] + for l in lines: + if not l: + continue + splitted_line = re.split(r'\s{2,}', l.strip()) + if len(splitted_line) > 2: + configured_vrfs.append(splitted_line[0]) + configured_vrfs.append('default') if value not in configured_vrfs: module.fail_json(msg='vrf `%s` is not configured on the system' % value) diff --git a/lib/ansible/modules/network/eos/eos_vrf.py b/lib/ansible/modules/network/eos/eos_vrf.py index 2e1b2365656..e26a9f12bce 100644 --- a/lib/ansible/modules/network/eos/eos_vrf.py +++ b/lib/ansible/modules/network/eos/eos_vrf.py @@ -184,29 +184,44 @@ def map_obj_to_commands(updates, module): def map_config_to_obj(module): objs = [] output = run_commands(module, ['show vrf']) - lines = output[0].strip().splitlines()[2:] - for l in lines: - if not l: + lines = output[0].strip().splitlines()[3:] + + out_len = len(lines) + index = 0 + while out_len > index: + line = lines[index] + if not line: continue - splitted_line = re.split(r'\s{2,}', l.strip()) + splitted_line = re.split(r'\s{2,}', line.strip()) if len(splitted_line) == 1: + index += 1 continue else: - obj = {} + obj = dict() obj['name'] = splitted_line[0] obj['rd'] = splitted_line[1] obj['interfaces'] = [] if len(splitted_line) > 4: obj['interfaces'] = [] + interfaces = splitted_line[4] + if interfaces.endswith(','): + while interfaces.endswith(','): + # gather all comma separated interfaces + if out_len <= index: + break + index += 1 + line = lines[index] + vrf_line = re.split(r'\s{2,}', line.strip()) + interfaces += vrf_line[-1] - for i in splitted_line[4].split(','): + for i in interfaces.split(','): obj['interfaces'].append(i.strip().lower()) - - objs.append(obj) + index += 1 + objs.append(obj) return objs @@ -308,5 +323,6 @@ def main(): module.exit_json(**result) + if __name__ == '__main__': main() diff --git a/test/integration/targets/eos_vrf/tests/cli/basic.yaml b/test/integration/targets/eos_vrf/tests/cli/basic.yaml index 748b53d8674..2413864c4af 100644 --- a/test/integration/targets/eos_vrf/tests/cli/basic.yaml +++ b/test/integration/targets/eos_vrf/tests/cli/basic.yaml @@ -2,27 +2,18 @@ - name: setup - remove vrf eos_vrf: - name: test - state: absent - authorize: yes - provider: "{{ cli }}" - become: yes - -- name: setup - remove vrf - eos_vrf: - name: test2 - state: absent - authorize: yes - provider: "{{ cli }}" - become: yes - -- name: setup - remove vrf - eos_vrf: - name: test3 + name: "{{ item }}" state: absent authorize: yes provider: "{{ cli }}" become: yes + with_items: + - test + - test1 + - test2 + - test3 + - test4 + - test5 - name: Create vrf eos_vrf: @@ -133,6 +124,66 @@ # Ensure sessions contains epoc. Will fail after 18th May 2033 - "'session_name' not in result.commands" +- name: Add multiple interfaces to vrf + eos_vrf: + name: test1 + rd: 1:202 + state: present + authorize: yes + interfaces: + - loopback10 + - loopback11 + - loopback12 + - loopback13 + - loopback14 + - loopback15 + - loopback1000 + provider: "{{ cli }}" + become: yes + register: result + +- assert: + that: + - "result.changed == true" + - "'interface loopback10' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'interface loopback11' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'interface loopback12' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'interface loopback13' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'interface loopback14' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'interface loopback15' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'interface loopback1000' in result.commands" + - "'vrf forwarding test1' in result.commands" + - "'ansible_1' in result.session_name" + +- name: Add multiple interfaces to vrf (idempotent) + eos_vrf: + name: test1 + rd: 1:202 + state: present + authorize: yes + interfaces: + - loopback10 + - loopback11 + - loopback12 + - loopback13 + - loopback14 + - loopback15 + - loopback1000 + provider: "{{ cli }}" + become: yes + register: result + +- assert: + that: + - "result.changed == false" + - "result.commands | length == 0" + - name: Create aggregate of VRFs eos_vrf: aggregate: @@ -216,6 +267,7 @@ - name: Delete aggregate of VRFs eos_vrf: aggregate: + - { name: test1 } - { name: test2 } - { name: test3 } - { name: test4 } @@ -228,6 +280,7 @@ - name: Delete VRFs again (idempotent) eos_vrf: aggregate: + - { name: test1 } - { name: test2 } - { name: test3 } - { name: test4 }