From 0b2619ff2b4dd28cb5e6557ac1c7c7d162f5e6f2 Mon Sep 17 00:00:00 2001 From: Ganesh Nalawade Date: Fri, 8 Sep 2017 08:28:43 +0530 Subject: [PATCH] Add lldp neighbor intent argument for vyos_interface (#29092) * Add lldp neighbor intent argument for vyos_interface * Add version_added info for neighbor argument * Fix CI issue --- .../modules/network/vyos/vyos_interface.py | 66 ++++++++++++++++- .../vyos_interface/tests/cli/intent.yaml | 73 +++++++++++++++++++ 2 files changed, 136 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/network/vyos/vyos_interface.py b/lib/ansible/modules/network/vyos/vyos_interface.py index 8325ea6133..6ab432a306 100644 --- a/lib/ansible/modules/network/vyos/vyos_interface.py +++ b/lib/ansible/modules/network/vyos/vyos_interface.py @@ -57,6 +57,18 @@ options: - Interface link status. default: auto choices: ['full', 'half', 'auto'] + neighbors: + description: + - Check the operational state of given interface C(name) for LLDP neighbor. + - The following suboptions are available. + suboptions: + host: + description: + - "LLDP neighbor host for given interface C(name)." + port: + description: + - "LLDP neighbor port to which given interface C(name) is connected." + version_added: 2.5 aggregate: description: List of Interfaces definitions. state: @@ -115,6 +127,19 @@ EXAMPLES = """ - name: eth1 - name: eth2 state: absent + +- name: Check lldp neighbors intent arguments + vyos_interface: + name: eth0 + neighbors: + - port: eth0 + host: netdev + +- name: Config + intent + vyos_interface: + name: eth1 + enabled: False + state: down """ RETURN = """ @@ -256,7 +281,8 @@ def map_params_to_obj(module): 'mtu': module.params['mtu'], 'duplex': module.params['duplex'], 'delay': module.params['delay'], - 'state': module.params['state'] + 'state': module.params['state'], + 'neighbors': module.params['neighbors'] } if module.params['enabled']: @@ -270,12 +296,14 @@ def map_params_to_obj(module): def check_declarative_intent_params(module, want, result): failed_conditions = [] - + have_neighbors = None for w in want: want_state = w.get('state') want_tx_rate = w.get('tx_rate') want_rx_rate = w.get('rx_rate') - if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate: + want_neighbors = w.get('neighbors') + + if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate and not want_neighbors: continue if result['changed']: @@ -294,12 +322,43 @@ def check_declarative_intent_params(module, want, result): if have_state is None or not conditional(want_state, have_state.strip().lower()): failed_conditions.append('state ' + 'eq(%s)' % want_state) + if want_neighbors: + have_host = [] + have_port = [] + if have_neighbors is None: + rc, have_neighbors, err = exec_command(module, 'show lldp neighbors detail') + if rc != 0: + module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) + + if have_neighbors: + lines = have_neighbors.strip().split('Interface: ') + for line in lines: + field = line.split('\n') + if field[0].split(',')[0].strip() == w['name']: + for item in field: + if item.strip().startswith('SysName:'): + have_host.append(item.split(':')[1].strip()) + if item.strip().startswith('PortDescr:'): + have_port.append(item.split(':')[1].strip()) + for item in want_neighbors: + host = item.get('host') + port = item.get('port') + if host and host not in have_host: + failed_conditions.append('host ' + host) + if port and port not in have_port: + failed_conditions.append('port ' + port) + return failed_conditions def main(): """ main entry point for module execution """ + neighbors_spec = dict( + host=dict(), + port=dict() + ) + element_spec = dict( name=dict(), description=dict(), @@ -307,6 +366,7 @@ def main(): mtu=dict(type='int'), duplex=dict(choices=['full', 'half', 'auto']), enabled=dict(default=True, type='bool'), + neighbors=dict(type='list', elements='dict', options=neighbors_spec), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent', 'up', 'down']) diff --git a/test/integration/targets/vyos_interface/tests/cli/intent.yaml b/test/integration/targets/vyos_interface/tests/cli/intent.yaml index 69afb7e2ee..d93ccf2567 100644 --- a/test/integration/targets/vyos_interface/tests/cli/intent.yaml +++ b/test/integration/targets/vyos_interface/tests/cli/intent.yaml @@ -1,6 +1,12 @@ --- - debug: msg="START vyos_interface cli/intent.yaml" +- name: Run vyos lsmod command + vyos_command: + commands: + - lsmod + register: lsmod_out + - name: Setup (interface is up) vyos_interface: name: eth1 @@ -20,6 +26,20 @@ that: - "result.failed == false" +- name: Check lldp neighbors intent arguments + vyos_interface: + name: eth0 + neighbors: + - port: eth0 + provider: "{{ cli }}" + when: "'virtio_net' not in lsmod_out.stdout[0]" + register: result + +- assert: + that: + - "result.failed == false" + when: "'virtio_net' not in lsmod_out.stdout[0]" + - name: Check intent arguments (failed condition) vyos_interface: name: eth1 @@ -33,6 +53,24 @@ - "result.failed == true" - "'state eq(down)' in result.failed_conditions" +- name: Check lldp neighbors intent arguments (failed) + vyos_interface: + name: eth0 + neighbors: + - port: dummy_port + host: dummy_host + provider: "{{ cli }}" + ignore_errors: yes + when: "'virtio_net' not in lsmod_out.stdout[0]" + register: result + +- assert: + that: + - "result.failed == true" + - "'host dummy_host' in result.failed_conditions" + - "'port dummy_port' in result.failed_conditions" + when: "'virtio_net' not in lsmod_out.stdout[0]" + - name: Config + intent vyos_interface: name: eth1 @@ -72,3 +110,38 @@ - assert: that: - "result.failed == false" + +- name: Check lldp neighbors intent aggregate arguments + vyos_interface: + aggregate: + - name: eth0 + neighbors: + - port: eth0 + provider: "{{ cli }}" + when: "'virtio_net' not in lsmod_out.stdout[0]" + register: result + +- assert: + that: + - "result.failed == false" + when: "'virtio_net' not in lsmod_out.stdout[0]" + +- name: Check lldp neighbors intent aggregate arguments (failed) + vyos_interface: + aggregate: + - name: eth0 + neighbors: + - port: eth0 + - port: dummy_port + host: dummy_host + provider: "{{ cli }}" + ignore_errors: yes + when: "'virtio_net' not in lsmod_out.stdout[0]" + register: result + +- assert: + that: + - "result.failed == true" + - "'host dummy_host' in result.failed_conditions" + - "'port dummy_port' in result.failed_conditions" + when: "'virtio_net' not in lsmod_out.stdout[0]"