diff --git a/lib/ansible/modules/network/nxos/nxos_pim.py b/lib/ansible/modules/network/nxos/nxos_pim.py index 076db417f8b..edf7f8eb2ae 100644 --- a/lib/ansible/modules/network/nxos/nxos_pim.py +++ b/lib/ansible/modules/network/nxos/nxos_pim.py @@ -34,7 +34,8 @@ options: ssm_range: description: - Configure group ranges for Source Specific Multicast (SSM). - Valid values are multicast addresses or the keyword 'none'. + Valid values are multicast addresses or the keyword 'none' + or keyword 'default' required: true ''' EXAMPLES = ''' @@ -75,7 +76,9 @@ def get_existing(module, args): value = '' if has_command: value = has_command.group('value') - existing[arg] = value + if value == '232.0.0.0/8': + value = '' # remove the reserved value + existing[arg] = value.split() return existing @@ -93,8 +96,13 @@ def get_commands(module, existing, proposed, candidate): proposed_commands = apply_key_map(PARAM_TO_COMMAND_KEYMAP, proposed) for key, value in proposed_commands.items(): - command = '{0} {1}'.format(key, value) - commands.append(command) + if key == 'ip pim ssm range' and value == 'default': + # no cmd needs a value but the actual value does not matter + command = 'no ip pim ssm range none' + commands.append(command) + else: + command = '{0} {1}'.format(key, value) + commands.append(command) if commands: candidate.add(commands, parents=[]) @@ -102,7 +110,7 @@ def get_commands(module, existing, proposed, candidate): def main(): argument_spec = dict( - ssm_range=dict(required=True, type='str'), + ssm_range=dict(required=True, type='list'), ) argument_spec.update(nxos_argument_spec) @@ -114,16 +122,29 @@ def main(): check_args(module, warnings) result = {'changed': False, 'commands': [], 'warnings': warnings} - splitted_ssm_range = module.params['ssm_range'].split('.') - if len(splitted_ssm_range) != 4 and module.params['ssm_range'] != 'none': - module.fail_json(msg="Valid ssm_range values are multicast addresses " - "or the keyword 'none'.") + ssm_range_list = module.params['ssm_range'] + for item in ssm_range_list: + splitted_ssm_range = item.split('.') + if len(splitted_ssm_range) != 4 and item != 'none' and item != 'default': + module.fail_json(msg="Valid ssm_range values are multicast addresses " + "or the keyword 'none' or the keyword 'default'.") args = PARAM_TO_COMMAND_KEYMAP.keys() existing = get_existing(module, args) - proposed = dict((k, v) for k, v in module.params.items() - if k in args and v != existing[k]) + proposed_args = dict((k, v) for k, v in module.params.items() if k in args) + + proposed = {} + for key, value in proposed_args.items(): + if key == 'ssm_range': + if value[0] == 'default': + if existing.get(key): + proposed[key] = 'default' + else: + v = sorted(set([str(i) for i in value])) + ex = sorted(set([str(i) for i in existing.get(key)])) + if v != ex: + proposed[key] = ' '.join(str(s) for s in v) candidate = CustomNetworkConfig(indent=3) get_commands(module, existing, proposed, candidate) diff --git a/test/integration/nxos.yaml b/test/integration/nxos.yaml index 2f67c59668f..ace802dbd6a 100644 --- a/test/integration/nxos.yaml +++ b/test/integration/nxos.yaml @@ -518,6 +518,15 @@ failed_modules: "{{ failed_modules }} + [ 'nxos_overlay_global' ]" test_failed: true + - block: + - include_role: + name: nxos_pim + when: "limit_to in ['*', 'nxos_pim']" + rescue: + - set_fact: + failed_modules: "{{ failed_modules }} + [ 'nxos_pim' ]" + test_failed: true + - block: - include_role: name: nxos_pim_interface diff --git a/test/integration/targets/nxos_pim/defaults/main.yaml b/test/integration/targets/nxos_pim/defaults/main.yaml new file mode 100644 index 00000000000..5f709c5aac1 --- /dev/null +++ b/test/integration/targets/nxos_pim/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/test/integration/targets/nxos_pim/meta/main.yml b/test/integration/targets/nxos_pim/meta/main.yml new file mode 100644 index 00000000000..ae741cbdc71 --- /dev/null +++ b/test/integration/targets/nxos_pim/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - prepare_nxos_tests diff --git a/test/integration/targets/nxos_pim/tasks/cli.yaml b/test/integration/targets/nxos_pim/tasks/cli.yaml new file mode 100644 index 00000000000..edbff7dfafb --- /dev/null +++ b/test/integration/targets/nxos_pim/tasks/cli.yaml @@ -0,0 +1,33 @@ +--- +- name: collect common cli test cases + find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: collect cli test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- set_fact: + test_cases: + files: "{{ test_cases.files }} + {{ cli_cases.files }}" + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test cases (connection=network_cli) + include: "{{ test_case_to_run }} ansible_connection=network_cli connection={}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + +- name: run test case (connection=local) + include: "{{ test_case_to_run }} ansible_connection=local connection={{ cli }}" + with_first_found: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/nxos_pim/tasks/main.yaml b/test/integration/targets/nxos_pim/tasks/main.yaml new file mode 100644 index 00000000000..fea9337c14c --- /dev/null +++ b/test/integration/targets/nxos_pim/tasks/main.yaml @@ -0,0 +1,7 @@ +--- +# Use block to ensure that both cli and nxapi tests +# will run even if there are failures or errors. +- block: + - { include: cli.yaml, tags: ['cli'] } + always: + - { include: nxapi.yaml, tags: ['nxapi'] } diff --git a/test/integration/targets/nxos_pim/tasks/nxapi.yaml b/test/integration/targets/nxos_pim/tasks/nxapi.yaml new file mode 100644 index 00000000000..68e96a29420 --- /dev/null +++ b/test/integration/targets/nxos_pim/tasks/nxapi.yaml @@ -0,0 +1,27 @@ +--- +- name: collect common nxapi test cases + find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: collect nxapi test cases + find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- set_fact: + test_cases: + files: "{{ test_cases.files }} + {{ nxapi_cases.files }}" + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test cases (connection=local) + include: "{{ test_case_to_run }} ansible_connection=local connection={{ nxapi }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/nxos_pim/tests/common/sanity.yaml b/test/integration/targets/nxos_pim/tests/common/sanity.yaml new file mode 100644 index 00000000000..cc27c46b14b --- /dev/null +++ b/test/integration/targets/nxos_pim/tests/common/sanity.yaml @@ -0,0 +1,74 @@ +--- +- debug: msg="START connection={{ ansible_connection }} nxos_pim sanity test" +- debug: msg="Using provider={{ connection.transport }}" + when: ansible_connection == "local" + +- name: "Setup: Disable feature PIM" + nxos_feature: &disable_feature + feature: pim + state: disabled + provider: "{{ connection }}" + +- name: "Setup: Enable feature PIM" + nxos_feature: + feature: pim + state: enabled + provider: "{{ connection }}" + +- name: "Setup: Configure ssm_range none" + nxos_pim: &none + ssm_range: "none" + provider: "{{ connection }}" + +- block: + - name: Configure ssm_range + nxos_pim: &configure + ssm_range: + - "239.128.1.0/24" + - "224.0.0.0/8" + provider: "{{ connection }}" + register: result + + - assert: &true + that: + - "result.changed == true" + + - name: Check idempotence + nxos_pim: *configure + register: result + + - assert: &false + that: + - "result.changed == false" + + - name: Configure ssm_range default + nxos_pim: &conf_default + ssm_range: "default" + provider: "{{ connection }}" + register: result + + - assert: *true + + - name: Check idempotence + nxos_pim: *conf_default + register: result + + - assert: *false + + - name: Configure ssm_range none + nxos_pim: *none + register: result + + - assert: *true + + - name: Check idempotence + nxos_pim: *none + register: result + + - assert: *false + + always: + - name: "Disable feature PIM" + nxos_feature: *disable_feature + +- debug: msg="END connection={{ ansible_connection }} nxos_pim sanity test"