From 07b097af7c17d5c365655aa1e2692c2f7035117f Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 28 Jul 2017 13:06:41 -0400 Subject: [PATCH] Fix nxos portchannel force option (#27190) * Add integration tests * Fix force option * Enable nxos_portchannel test * Satisfy ansibot demands --- .../modules/network/nxos/nxos_portchannel.py | 28 +++--- test/integration/nxos.yaml | 10 +- .../nxos_portchannel/defaults/main.yaml | 2 + .../targets/nxos_portchannel/meta/main.yml | 2 + .../targets/nxos_portchannel/tasks/cli.yaml | 15 +++ .../targets/nxos_portchannel/tasks/main.yaml | 3 + .../targets/nxos_portchannel/tasks/nxapi.yaml | 28 ++++++ .../nxos_portchannel/tests/cli/sanity.yaml | 4 + .../nxos_portchannel/tests/common/sanity.yaml | 99 +++++++++++++++++++ .../nxos_portchannel/tests/nxapi/sanity.yaml | 4 + 10 files changed, 183 insertions(+), 12 deletions(-) create mode 100644 test/integration/targets/nxos_portchannel/defaults/main.yaml create mode 100644 test/integration/targets/nxos_portchannel/meta/main.yml create mode 100644 test/integration/targets/nxos_portchannel/tasks/cli.yaml create mode 100644 test/integration/targets/nxos_portchannel/tasks/main.yaml create mode 100644 test/integration/targets/nxos_portchannel/tasks/nxapi.yaml create mode 100644 test/integration/targets/nxos_portchannel/tests/cli/sanity.yaml create mode 100644 test/integration/targets/nxos_portchannel/tests/common/sanity.yaml create mode 100644 test/integration/targets/nxos_portchannel/tests/nxapi/sanity.yaml diff --git a/lib/ansible/modules/network/nxos/nxos_portchannel.py b/lib/ansible/modules/network/nxos/nxos_portchannel.py index 2acb8bada40..f9aaa981a74 100644 --- a/lib/ansible/modules/network/nxos/nxos_portchannel.py +++ b/lib/ansible/modules/network/nxos/nxos_portchannel.py @@ -255,16 +255,18 @@ def get_existing(module, args): return existing, interface_exist -def config_portchannel(proposed, mode, group): +def config_portchannel(proposed, mode, group, force): commands = [] + # NOTE: Leading whitespace for force option is important + force = ' force' if force else '' config_args = { - 'mode': 'channel-group {group} mode {mode}', + 'mode': 'channel-group {group}{force} mode {mode}', 'min_links': 'lacp min-links {min_links}', } for member in proposed.get('members', []): commands.append('interface {0}'.format(member)) - commands.append(config_args.get('mode').format(group=group, mode=mode)) + commands.append(config_args.get('mode').format(group=group, force=force, mode=mode)) min_links = proposed.get('min_links', None) if min_links: @@ -276,7 +278,7 @@ def config_portchannel(proposed, mode, group): return commands -def get_commands_to_add_members(proposed, existing, module): +def get_commands_to_add_members(proposed, existing, force, module): try: proposed_members = proposed['members'] except KeyError: @@ -290,11 +292,13 @@ def get_commands_to_add_members(proposed, existing, module): members_to_add = list(set(proposed_members).difference(existing_members)) commands = [] + # NOTE: Leading whitespace for force option is important + force = ' force' if force else '' if members_to_add: for member in members_to_add: commands.append('interface {0}'.format(member)) - commands.append('channel-group {0} mode {1}'.format( - existing['group'], proposed['mode'])) + commands.append('channel-group {0}{1} mode {2}'.format( + existing['group'], force, proposed['mode'])) return commands @@ -320,7 +324,7 @@ def get_commands_to_remove_members(proposed, existing, module): return commands -def get_commands_if_mode_change(proposed, existing, group, mode, module): +def get_commands_if_mode_change(proposed, existing, group, mode, force, module): try: proposed_members = proposed['members'] except KeyError: @@ -346,6 +350,8 @@ def get_commands_if_mode_change(proposed, existing, group, mode, module): members_with_mode_change.append(interface) commands = [] + # NOTE: Leading whitespace for force option is important + force = ' force' if force else '' if members_with_mode_change: for member in members_with_mode_change: commands.append('interface {0}'.format(member)) @@ -353,7 +359,7 @@ def get_commands_if_mode_change(proposed, existing, group, mode, module): for member in members_with_mode_change: commands.append('interface {0}'.format(member)) - commands.append('channel-group {0} mode {1}'.format(group, mode)) + commands.append('channel-group {0}{1} mode {2}'.format(group, force, mode)) return commands @@ -388,7 +394,7 @@ def state_present(module, existing, proposed, interface_exist, force, warnings): min_links = module.params['min_links'] if not interface_exist: - command = config_portchannel(proposed, mode, group) + command = config_portchannel(proposed, mode, group, force) commands.append(command) commands.insert(0, 'interface port-channel{0}'.format(group)) warnings.append("The proposed port-channel interface did not " @@ -400,10 +406,10 @@ def state_present(module, existing, proposed, interface_exist, force, warnings): command = get_commands_to_remove_members(proposed, existing, module) commands.append(command) - command = get_commands_to_add_members(proposed, existing, module) + command = get_commands_to_add_members(proposed, existing, force, module) commands.append(command) - mode_command = get_commands_if_mode_change(proposed, existing, group, mode, module) + mode_command = get_commands_if_mode_change(proposed, existing, group, mode, force, module) commands.insert(0, mode_command) if min_links: diff --git a/test/integration/nxos.yaml b/test/integration/nxos.yaml index b5e353b0cb7..84b18a06d6c 100644 --- a/test/integration/nxos.yaml +++ b/test/integration/nxos.yaml @@ -204,6 +204,15 @@ failed_modules: "{{ failed_modules }} + [ 'nxos_rollback' ]" test_failed: true + - block: + - include_role: + name: nxos_portchannel + when: "limit_to in ['*', 'nxos_portchannel']" + rescue: + - set_fact: + failed_modules: "{{ failed_modules }} + [ 'nxos_portchannel' ]" + test_failed: true + - block: - include_role: name: nxos_logging @@ -211,7 +220,6 @@ rescue: - set_fact: test_failed=true - ########### - debug: var=failed_modules when: test_failed diff --git a/test/integration/targets/nxos_portchannel/defaults/main.yaml b/test/integration/targets/nxos_portchannel/defaults/main.yaml new file mode 100644 index 00000000000..5f709c5aac1 --- /dev/null +++ b/test/integration/targets/nxos_portchannel/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/test/integration/targets/nxos_portchannel/meta/main.yml b/test/integration/targets/nxos_portchannel/meta/main.yml new file mode 100644 index 00000000000..ae741cbdc71 --- /dev/null +++ b/test/integration/targets/nxos_portchannel/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - prepare_nxos_tests diff --git a/test/integration/targets/nxos_portchannel/tasks/cli.yaml b/test/integration/targets/nxos_portchannel/tasks/cli.yaml new file mode 100644 index 00000000000..d675462dd02 --- /dev/null +++ b/test/integration/targets/nxos_portchannel/tasks/cli.yaml @@ -0,0 +1,15 @@ +--- +- name: collect all cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/nxos_portchannel/tasks/main.yaml b/test/integration/targets/nxos_portchannel/tasks/main.yaml new file mode 100644 index 00000000000..4b0f8c64d90 --- /dev/null +++ b/test/integration/targets/nxos_portchannel/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- { include: cli.yaml, tags: ['cli'] } +- { include: nxapi.yaml, tags: ['nxapi'] } diff --git a/test/integration/targets/nxos_portchannel/tasks/nxapi.yaml b/test/integration/targets/nxos_portchannel/tasks/nxapi.yaml new file mode 100644 index 00000000000..ea525379f7f --- /dev/null +++ b/test/integration/targets/nxos_portchannel/tasks/nxapi.yaml @@ -0,0 +1,28 @@ +--- +- name: collect all nxapi test cases + find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + register: test_cases + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: enable nxapi + nxos_config: + lines: + - feature nxapi + - nxapi http port 80 + provider: "{{ cli }}" + +- name: run test case + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + +- name: disable nxapi + nxos_config: + lines: + - no feature nxapi + provider: "{{ cli }}" diff --git a/test/integration/targets/nxos_portchannel/tests/cli/sanity.yaml b/test/integration/targets/nxos_portchannel/tests/cli/sanity.yaml new file mode 100644 index 00000000000..420af7420e9 --- /dev/null +++ b/test/integration/targets/nxos_portchannel/tests/cli/sanity.yaml @@ -0,0 +1,4 @@ +--- +- set_fact: connection="{{ cli }}" + +- import_tasks: "{{ role_path }}/tests/common/sanity.yaml" diff --git a/test/integration/targets/nxos_portchannel/tests/common/sanity.yaml b/test/integration/targets/nxos_portchannel/tests/common/sanity.yaml new file mode 100644 index 00000000000..2d26696fe7e --- /dev/null +++ b/test/integration/targets/nxos_portchannel/tests/common/sanity.yaml @@ -0,0 +1,99 @@ +--- +- debug: msg="START TRANSPORT:{{ connection.transport }} nxos_portchannel sanity test" + +- set_fact: testint1="{{ nxos_int1 }}" +- set_fact: testint2="{{ nxos_int2 }}" + +- name: "Enable feature LACP" + nxos_feature: + feature: lacp + state: enabled + provider: "{{ connection }}" + ignore_errors: yes + +- name: "Put interface {{testint1}} into default state" + nxos_config: &intdefault1 + lines: + - "default interface {{ testint1 }}" + provider: "{{ connection }}" + ignore_errors: yes + +- name: "Put interface {{testint2}} into default state" + nxos_config: &intdefault2 + lines: + - "default interface {{ testint2 }}" + provider: "{{ connection }}" + ignore_errors: yes + +- name: Remove possibly configured port-channel 99 + nxos_portchannel: &delpc + group: 99 + members: ["{{ testint1 }}", "{{ testint2 }}"] + force: 'true' + state: absent + timeout: 60 + provider: "{{ connection }}" + +- block: + - name: Configure port-channel mode active + nxos_portchannel: &configpc + group: 99 + members: ["{{ testint1 }}", "{{ testint2 }}"] + mode: active + force: 'true' + state: present + timeout: 60 + provider: "{{ connection }}" + register: result + + - assert: &true + that: + - "result.changed == true" + + - name: Check Idempotence + nxos_portchannel: *configpc + register: result + + - assert: &false + that: + - "result.changed == false" + + - name: Configure port-channel mode passive + nxos_portchannel: &configpcpassive + group: 99 + members: ["{{ testint1 }}", "{{ testint2 }}"] + mode: passive + force: 'true' + state: present + timeout: 60 + provider: "{{ connection }}" + register: result + + - assert: *true + + - name: Check Idempotence + nxos_portchannel: *configpcpassive + register: result + + - assert: *false + + - name: Configure port-channel + nxos_portchannel: *delpc + register: result + + - assert: *true + + rescue: + - name: "Disable feature LACP" + nxos_feature: + feature: lacp + state: disabled + timeout: 60 + provider: "{{ connection }}" + + always: + - name: Delete port-channel + nxos_portchannel: *delpc + register: result + + - debug: msg="END TRANSPORT:{{ connection.transport }} nxos_portchannel sanity test" diff --git a/test/integration/targets/nxos_portchannel/tests/nxapi/sanity.yaml b/test/integration/targets/nxos_portchannel/tests/nxapi/sanity.yaml new file mode 100644 index 00000000000..e30ea6eaf70 --- /dev/null +++ b/test/integration/targets/nxos_portchannel/tests/nxapi/sanity.yaml @@ -0,0 +1,4 @@ +--- +- set_fact: connection="{{ nxapi }}" + +- import_tasks: "{{ role_path }}/tests/common/sanity.yaml"