diff --git a/lib/ansible/modules/network/onyx/onyx_igmp_interface.py b/lib/ansible/modules/network/onyx/onyx_igmp_interface.py new file mode 100644 index 0000000000..a067ef2cd5 --- /dev/null +++ b/lib/ansible/modules/network/onyx/onyx_igmp_interface.py @@ -0,0 +1,136 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = """ +--- +module: onyx_igmp_interface +version_added: "2.8" +author: "Anas Badaha (@anasb)" +short_description: Configures IGMP interface parameters +description: + - This module provides declarative management of IGMP interface configuration + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.8130 +options: + name: + description: + - interface name that we want to configure IGMP on it + required: true + state: + description: + - IGMP Interface state. + choices: ['enabled', 'disabled'] + default: enabled +""" + +EXAMPLES = """ +- name: configure igmp interfcae + onyx_igmp_interface: + state: enabled + name: Eth1/1 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/1 ip igmp snooping fast-leave +""" + +import re +from ansible.module_utils.basic import AnsibleModule + +from ansible.module_utils.network.onyx.onyx import show_cmd +from ansible.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxIgmpInterfaceModule(BaseOnyxModule): + IF_NAME_REGEX = re.compile(r"^(Eth\d+\/\d+|Eth\d+\/\d+\d+)$") + + def init_module(self): + """ initialize module + """ + element_spec = dict( + state=dict(choices=['enabled', 'disabled'], default='enabled'), + name=dict(required=True) + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + match = self.IF_NAME_REGEX.match(self._required_config["name"]) + if not match: + AttributeError("Please Insert Valide Interface Name") + + self.validate_param_values(self._required_config) + + def _set_igmp_config(self, igmp_interfaces_config): + if not igmp_interfaces_config: + return + name = self._required_config.get('name') + interface_state = igmp_interfaces_config[name][0].get('leave-mode') + if interface_state == "Fast": + self._current_config['state'] = "enabled" + else: + self._current_config['state'] = "disabled" + + def _show_igmp_interfaces(self): + cmd = "show ip igmp snooping interfaces" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + igmp_interfaces_config = self._show_igmp_interfaces() + if igmp_interfaces_config: + self._set_igmp_config(igmp_interfaces_config) + + def generate_commands(self): + req_state = self._required_config['state'] + self._req_val = self._required_config.get('name').replace("Eth", "ethernet ") + + if req_state == 'enabled': + self._generate_igmp_interface_cmds() + else: + self._generate_no_igmp_cmds() + + def _generate_igmp_interface_cmds(self): + curr_state = self._current_config.get('state', 'enabled') + if curr_state == 'enabled': + pass + + elif curr_state == 'disabled': + self._commands.append('interface %s ip igmp snooping fast-leave' % self._req_val) + + def _generate_no_igmp_cmds(self): + curr_state = self._current_config.get('state', 'enabled') + if curr_state == 'enabled': + self._commands.append('interface %s no ip igmp snooping fast-leave' % self._req_val) + else: + pass + + +def main(): + """ main entry point for module execution + """ + OnyxIgmpInterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/test/units/modules/network/onyx/fixtures/onyx_show_igmp_interfaces.cfg b/test/units/modules/network/onyx/fixtures/onyx_show_igmp_interfaces.cfg new file mode 100644 index 0000000000..22641d8b48 --- /dev/null +++ b/test/units/modules/network/onyx/fixtures/onyx_show_igmp_interfaces.cfg @@ -0,0 +1,162 @@ +{ + "Eth1/31": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/11": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/10": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/13": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/12": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/15": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/14": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/17": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/16": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/19": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/18": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/5": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/4": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/7": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/6": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/1": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/3": [ + { + "leave-mode": "Fast" + } + ], + "Eth1/2": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/9": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/8": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/32": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/24": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/25": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/26": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/27": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/20": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/21": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/22": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/23": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/30": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/28": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/29": [ + { + "leave-mode": "Normal" + } + ] +} \ No newline at end of file diff --git a/test/units/modules/network/onyx/test_onyx_igmp_interface.py b/test/units/modules/network/onyx/test_onyx_igmp_interface.py new file mode 100644 index 0000000000..e8f4373ffb --- /dev/null +++ b/test/units/modules/network/onyx/test_onyx_igmp_interface.py @@ -0,0 +1,69 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.compat.tests.mock import patch +from ansible.modules.network.onyx import onyx_igmp_interface +from units.modules.utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxIgmpInterfaceModule(TestOnyxModule): + + module = onyx_igmp_interface + + def setUp(self): + super(TestOnyxIgmpInterfaceModule, self).setUp() + + self.mock_get_config = patch.object(onyx_igmp_interface.OnyxIgmpInterfaceModule, "_show_igmp_interfaces") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxIgmpInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_igmp_interfaces.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_igmp_interface_enabled_no_change(self): + set_module_args(dict(state='enabled', name='Eth1/3')) + self.execute_module(changed=False) + + def test_igmp_interface_enabled_change(self): + set_module_args(dict(state='enabled', name='Eth1/1')) + commands = ['interface ethernet 1/1 ip igmp snooping fast-leave'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_interface_disabled_no_change(self): + set_module_args(dict(state='disabled', name='Eth1/1')) + self.execute_module(changed=False) + + def test_igmp_interface_disabled_change(self): + set_module_args(dict(state='disabled', name='Eth1/3')) + commands = ['interface ethernet 1/3 no ip igmp snooping fast-leave'] + self.execute_module(changed=True, commands=commands)