From eb33cc88bdaee747a36d583ec7523d3493899a33 Mon Sep 17 00:00:00 2001 From: Ganesh Nalawade Date: Mon, 14 Aug 2017 10:17:41 +0530 Subject: [PATCH] Add state intent argument in vyos interface (#28066) * Add state intent argument in vyos interface * State intent argument support * Integration test for supported intent arguments * Add intent testcase * FIx ci issue --- .../modules/network/vyos/vyos_interface.py | 76 ++++++++++++++----- .../net_interface/tests/vyos/basic.yaml | 12 +-- .../net_interface/tests/vyos/intent.yaml | 74 ++++++++++++++++++ .../vyos_interface/tests/cli/basic.yaml | 12 +-- .../vyos_interface/tests/cli/intent.yaml | 74 ++++++++++++++++++ 5 files changed, 215 insertions(+), 33 deletions(-) create mode 100644 test/integration/targets/net_interface/tests/vyos/intent.yaml create mode 100644 test/integration/targets/vyos_interface/tests/cli/intent.yaml diff --git a/lib/ansible/modules/network/vyos/vyos_interface.py b/lib/ansible/modules/network/vyos/vyos_interface.py index 1d5aad37a42..212346af0bf 100644 --- a/lib/ansible/modules/network/vyos/vyos_interface.py +++ b/lib/ansible/modules/network/vyos/vyos_interface.py @@ -55,19 +55,8 @@ options: - Interface link status. default: auto choices: ['full', 'half', 'auto'] - tx_rate: - description: - - Transmit rate. - rx_rate: - description: - - Receiver rate. aggregate: description: List of Interfaces definitions. - purge: - description: - - Purge Interfaces not defined in the aggregate parameter. - This applies only for logical interface. - default: no state: description: - State of the Interface configuration, C(up) means present and @@ -90,12 +79,12 @@ EXAMPLES = """ - name: make interface down vyos_interface: name: eth0 - state: down + enabled: False - name: make interface up vyos_interface: name: eth0 - state: up + enabled: True - name: Configure interface speed, mtu, duplex vyos_interface: @@ -119,7 +108,12 @@ commands: """ import re +from time import sleep + +from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import exec_command +from ansible.module_utils.network_common import conditional from ansible.module_utils.vyos import load_config, get_config from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -194,7 +188,6 @@ def map_config_to_obj(module): match = re.search(r'%s (\S+)' % name, line, re.M) if match: - param = match.group(1) if param == 'description': match = re.search(r'description (\S+)', line, re.M) @@ -234,15 +227,23 @@ def map_params_to_obj(module): if item not in d: d[item] = None - d['description'] = DEFAULT_DESCRIPTION + if d.get('description') is None: + d['description'] = DEFAULT_DESCRIPTION + if not d.get('state'): d['state'] = module.params['state'] - if d['state'] in ('present', 'up'): + if d.get('enabled') is None: + d['enabled'] = module.params['enabled'] + + if d['enabled']: d['disable'] = False else: d['disable'] = True + if d.get('delay') is None: + d['delay'] = module.params['delay'] + if d.get('speed'): d['speed'] = str(d['speed']) @@ -254,11 +255,11 @@ def map_params_to_obj(module): 'speed': module.params['speed'], 'mtu': module.params['mtu'], 'duplex': module.params['duplex'], + 'delay': module.params['delay'], 'state': module.params['state'] } - state = module.params['state'] - if state == 'present' or state == 'up': + if module.params['enabled']: params.update({'disable': False}) else: params.update({'disable': True}) @@ -267,6 +268,35 @@ def map_params_to_obj(module): return obj +def check_declarative_intent_params(module, want, result): + failed_conditions = [] + + 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: + continue + + if result['changed']: + sleep(w['delay']) + + command = 'show interfaces ethernet %s' % w['name'] + rc, out, err = exec_command(module, command) + if rc != 0: + module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) + + if want_state in ('up', 'down'): + match = re.search(r'%s (\w+)' % 'state', out, re.M) + have_state = None + if match: + have_state = match.group(1) + if have_state is None or not conditional(want_state, have_state.strip().lower()): + failed_conditions.append('state ' + 'eq(%s)' % want_state) + + return failed_conditions + + def main(): """ main entry point for module execution """ @@ -276,10 +306,9 @@ def main(): speed=dict(), mtu=dict(type='int'), duplex=dict(choices=['full', 'half', 'auto']), - tx_rate=dict(), - rx_rate=dict(), + enabled=dict(default=True, type='bool'), + delay=dict(default=10, type='int'), aggregate=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent', 'up', 'down']) ) @@ -318,6 +347,11 @@ def main(): result['diff'] = {'prepared': diff} result['changed'] = True + failed_conditions = check_declarative_intent_params(module, want, result) + + if failed_conditions: + msg = 'One or more conditional statements have not been satisfied' + module.fail_json(msg=msg, failed_conditions=failed_conditions) module.exit_json(**result) if __name__ == '__main__': diff --git a/test/integration/targets/net_interface/tests/vyos/basic.yaml b/test/integration/targets/net_interface/tests/vyos/basic.yaml index 94ca7507649..777016964ab 100644 --- a/test/integration/targets/net_interface/tests/vyos/basic.yaml +++ b/test/integration/targets/net_interface/tests/vyos/basic.yaml @@ -59,7 +59,7 @@ - name: Disable interface net_interface: name: eth1 - state: down + enabled: False register: result - assert: @@ -70,7 +70,7 @@ - name: Enable interface net_interface: name: eth1 - state: up + enabled: True register: result - assert: @@ -138,8 +138,8 @@ - name: Disable interface on aggregate net_interface: aggregate: - - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, state: down} - - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, state: down} + - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, enabled: False} + - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, enabled: False} register: result - assert: @@ -151,8 +151,8 @@ - name: Enable interface on aggregate net_interface: aggregate: - - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, state: present} - - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, state: present} + - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, enabled: True} + - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, enabled: True} register: result - assert: diff --git a/test/integration/targets/net_interface/tests/vyos/intent.yaml b/test/integration/targets/net_interface/tests/vyos/intent.yaml new file mode 100644 index 00000000000..d9ba147982c --- /dev/null +++ b/test/integration/targets/net_interface/tests/vyos/intent.yaml @@ -0,0 +1,74 @@ +--- +- debug: msg="START net_interface vyos/intent.yaml" + +- name: Setup (interface is up) + net_interface: + name: eth1 + enabled: True + state: present + provider: "{{ cli }}" + register: result + +- name: Check intent arguments + net_interface: + name: eth1 + state: up + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.failed == false" + +- name: Check intent arguments (failed condition) + net_interface: + name: eth1 + state: down + provider: "{{ cli }}" + ignore_errors: yes + register: result + +- assert: + that: + - "result.failed == true" + - "'state eq(down)' in result.failed_conditions" + +- name: Config + intent + net_interface: + name: eth1 + enabled: False + state: down + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.failed == false" + +- name: Config + intent (fail) + net_interface: + name: eth1 + enabled: False + state: up + provider: "{{ cli }}" + ignore_errors: yes + register: result + +- assert: + that: + - "result.failed == true" + - "'state eq(up)' in result.failed_conditions" + +- name: Aggregate config + intent (pass) + net_interface: + aggregate: + - name: eth1 + enabled: True + state: up + provider: "{{ cli }}" + ignore_errors: yes + register: result + +- assert: + that: + - "result.failed == false" diff --git a/test/integration/targets/vyos_interface/tests/cli/basic.yaml b/test/integration/targets/vyos_interface/tests/cli/basic.yaml index 1f3a65d0e73..a4c3a7cd403 100644 --- a/test/integration/targets/vyos_interface/tests/cli/basic.yaml +++ b/test/integration/targets/vyos_interface/tests/cli/basic.yaml @@ -84,7 +84,7 @@ - name: Disable interface vyos_interface: name: eth1 - state: down + enabled: False register: result - assert: @@ -95,7 +95,7 @@ - name: Enable interface vyos_interface: name: eth1 - state: up + enabled: True register: result - assert: @@ -167,8 +167,8 @@ - name: Disable interface on aggregate vyos_interface: aggregate: - - { name: eth1, description: test-interface-1, state: down} - - { name: eth2, description: test-interface-2, state: down} + - { name: eth1, description: test-interface-1, enabled: False} + - { name: eth2, description: test-interface-2, enabled: False} register: result - assert: @@ -180,8 +180,8 @@ - name: Enable interface on aggregate vyos_interface: aggregate: - - { name: eth1, description: test-interface-1, state: present} - - { name: eth2, description: test-interface-2, state: present} + - { name: eth1, description: test-interface-1, enabled: True} + - { name: eth2, description: test-interface-2, enabled: True} register: result - assert: diff --git a/test/integration/targets/vyos_interface/tests/cli/intent.yaml b/test/integration/targets/vyos_interface/tests/cli/intent.yaml new file mode 100644 index 00000000000..69afb7e2ee3 --- /dev/null +++ b/test/integration/targets/vyos_interface/tests/cli/intent.yaml @@ -0,0 +1,74 @@ +--- +- debug: msg="START vyos_interface cli/intent.yaml" + +- name: Setup (interface is up) + vyos_interface: + name: eth1 + enabled: True + state: present + provider: "{{ cli }}" + register: result + +- name: Check intent arguments + vyos_interface: + name: eth1 + state: up + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.failed == false" + +- name: Check intent arguments (failed condition) + vyos_interface: + name: eth1 + state: down + provider: "{{ cli }}" + ignore_errors: yes + register: result + +- assert: + that: + - "result.failed == true" + - "'state eq(down)' in result.failed_conditions" + +- name: Config + intent + vyos_interface: + name: eth1 + enabled: False + state: down + provider: "{{ cli }}" + register: result + +- assert: + that: + - "result.failed == false" + +- name: Config + intent (fail) + vyos_interface: + name: eth1 + enabled: False + state: up + provider: "{{ cli }}" + ignore_errors: yes + register: result + +- assert: + that: + - "result.failed == true" + - "'state eq(up)' in result.failed_conditions" + +- name: Aggregate config + intent (pass) + vyos_interface: + aggregate: + - name: eth1 + enabled: True + state: up + provider: "{{ cli }}" + ignore_errors: yes + register: result + +- assert: + that: + - "result.failed == false"