Adding IGMP vlan module for onyx switches (#47811)
Signed-off-by: Anas Badaha <anasb@mellanox.com>
This commit is contained in:
parent
760e57f877
commit
dc8b3e94ad
5 changed files with 686 additions and 0 deletions
436
lib/ansible/modules/network/onyx/onyx_igmp_vlan.py
Normal file
436
lib/ansible/modules/network/onyx/onyx_igmp_vlan.py
Normal file
|
@ -0,0 +1,436 @@
|
||||||
|
#!/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_vlan
|
||||||
|
version_added: '2.8'
|
||||||
|
author: 'Anas Badaha(@anasb)'
|
||||||
|
short_description: Configures IGMP Vlan parameters
|
||||||
|
description:
|
||||||
|
- This module provides declarative management of IGMP vlan configuration on Mellanox ONYX network devices.
|
||||||
|
notes:
|
||||||
|
- Tested on ONYX 3.7.0932-01
|
||||||
|
options:
|
||||||
|
vlan_id:
|
||||||
|
description:
|
||||||
|
- VLAN ID, vlan should exist.
|
||||||
|
required: true
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- IGMP state.
|
||||||
|
choices: ['enabled', 'disabled']
|
||||||
|
default: enabled
|
||||||
|
mrouter:
|
||||||
|
description:
|
||||||
|
- Configure ip igmp snooping mrouter port on vlan
|
||||||
|
suboptions:
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- Enable IGMP snooping mrouter on vlan interface.
|
||||||
|
choices: ['enabled', 'disabled']
|
||||||
|
default: enabled
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Configure mrouter interface
|
||||||
|
required: true
|
||||||
|
querier:
|
||||||
|
description:
|
||||||
|
- Configure the IGMP querier parameters
|
||||||
|
suboptions:
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- Enable IGMP snooping querier on vlan in the switch.
|
||||||
|
choices: ['enabled', 'disabled']
|
||||||
|
default: enabled
|
||||||
|
interval:
|
||||||
|
description:
|
||||||
|
- Update time interval between querier queries, range 60-600
|
||||||
|
address:
|
||||||
|
description:
|
||||||
|
- Update IP address for the querier
|
||||||
|
static_groups:
|
||||||
|
description:
|
||||||
|
- List of IGMP static groups.
|
||||||
|
suboptions:
|
||||||
|
multicast_ip_address:
|
||||||
|
description:
|
||||||
|
- Configure static IP multicast group, range 224.0.1.0-239.255.255.25.
|
||||||
|
required: true
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- interface name to configure static groups on it.
|
||||||
|
sources:
|
||||||
|
description:
|
||||||
|
- List of IP sources to be configured
|
||||||
|
version:
|
||||||
|
description:
|
||||||
|
- IGMP snooping operation version on this vlan
|
||||||
|
choices: ['V2','V3']
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = """
|
||||||
|
- name: configure igmp vlan
|
||||||
|
onyx_igmp_vlan:
|
||||||
|
state: enabled
|
||||||
|
vlan_id: 10
|
||||||
|
version:
|
||||||
|
V2
|
||||||
|
querier:
|
||||||
|
state: enabled
|
||||||
|
interval: 70
|
||||||
|
address: 10.11.121.13
|
||||||
|
mrouter:
|
||||||
|
state: disabled
|
||||||
|
name: Eth1/2
|
||||||
|
static_groups:
|
||||||
|
- multicast_ip_address: 224.5.5.8
|
||||||
|
name: Eth1/1
|
||||||
|
sources:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 1.1.1.2
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = """
|
||||||
|
commands:
|
||||||
|
description: The list of configuration mode commands to send to the device.
|
||||||
|
returned: always
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
- vlan 10 ip igmp snooping
|
||||||
|
- vlan 10 ip igmp snooping static-group 224.5.5.5 interface ethernet 1/1
|
||||||
|
"""
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def _ip_to_int(addr):
|
||||||
|
return struct.unpack("!I", socket.inet_aton(addr))[0]
|
||||||
|
|
||||||
|
|
||||||
|
class OnyxIgmpVlanModule(BaseOnyxModule):
|
||||||
|
MIN_MULTICAST_IP = _ip_to_int("224.0.1.0")
|
||||||
|
MAX_MULTICAST_IP = _ip_to_int("239.255.255.255")
|
||||||
|
|
||||||
|
def init_module(self):
|
||||||
|
""" initialize module
|
||||||
|
"""
|
||||||
|
mrouter_spec = dict(name=dict(required=True),
|
||||||
|
state=dict(choices=['enabled', 'disabled'], default='enabled'))
|
||||||
|
querier_spec = dict(state=dict(choices=['enabled', 'disabled'], default='enabled'),
|
||||||
|
interval=dict(type='int'), address=dict())
|
||||||
|
static_groups_spec = dict(multicast_ip_address=dict(required=True),
|
||||||
|
name=dict(required=True), sources=dict(type='list'))
|
||||||
|
element_spec = dict(vlan_id=dict(type='int', required=True),
|
||||||
|
state=dict(choices=['enabled', 'disabled'], default='enabled'),
|
||||||
|
querier=dict(type='dict', options=querier_spec),
|
||||||
|
static_groups=dict(type='list', elements='dict', options=static_groups_spec),
|
||||||
|
mrouter=dict(type='dict', options=mrouter_spec),
|
||||||
|
version=dict(choices=['V2', 'V3']))
|
||||||
|
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)
|
||||||
|
self.validate_param_values(self._required_config)
|
||||||
|
|
||||||
|
def _validate_attr_is_not_none(self, attr_name, attr_value):
|
||||||
|
if attr_name == 'vlan_id' or attr_name == 'state':
|
||||||
|
pass
|
||||||
|
elif attr_value is not None:
|
||||||
|
self._module.fail_json(msg='Can not set %s value on switch while state is disabled' % attr_name)
|
||||||
|
|
||||||
|
def validate_param_values(self, obj, param=None):
|
||||||
|
if obj['state'] == 'disabled':
|
||||||
|
for attr_name in obj:
|
||||||
|
self._validate_attr_is_not_none(attr_name, obj[attr_name])
|
||||||
|
super(OnyxIgmpVlanModule, self).validate_param_values(obj, param)
|
||||||
|
|
||||||
|
def validate_querier(self, value):
|
||||||
|
interval = value.get('interval')
|
||||||
|
if interval and not 60 <= int(interval) <= 600:
|
||||||
|
self._module.fail_json(msg='query-interval value must be between 60 and 600')
|
||||||
|
|
||||||
|
def validate_static_groups(self, value):
|
||||||
|
multicast_ip = value.get('multicast_ip_address')
|
||||||
|
multicast_ip = _ip_to_int(multicast_ip)
|
||||||
|
|
||||||
|
if multicast_ip < self.MIN_MULTICAST_IP or multicast_ip > self.MAX_MULTICAST_IP:
|
||||||
|
self._module.fail_json(msg='multicast IP address must be in range 224.0.1.0 - 239.255.255.255')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_curr_mrouter_config(mrouter_port):
|
||||||
|
if mrouter_port == "none":
|
||||||
|
return {'state': 'disabled'}
|
||||||
|
else:
|
||||||
|
return {'state': 'enabled',
|
||||||
|
'name': mrouter_port}
|
||||||
|
|
||||||
|
def _get_curr_querier_config(self, querier_config):
|
||||||
|
if "Non-Querier" in querier_config:
|
||||||
|
return {'state': 'disabled'}
|
||||||
|
elif "Querier" in querier_config:
|
||||||
|
igmp_querier_config = self._show_igmp_querier_config()[0]
|
||||||
|
snooping_querier_info = igmp_querier_config["Snooping querier information for VLAN %d" % (
|
||||||
|
self._required_config['vlan_id'])]
|
||||||
|
snooping_querier_info = snooping_querier_info[1]
|
||||||
|
interval = int(snooping_querier_info["Query interval"])
|
||||||
|
address = snooping_querier_info["Configured querier IP address"]
|
||||||
|
return {'state': 'enabled',
|
||||||
|
'interval': interval,
|
||||||
|
'address': address}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_curr_version(version):
|
||||||
|
if "V3" in version:
|
||||||
|
return "V3"
|
||||||
|
elif "V2" in version:
|
||||||
|
return "V2"
|
||||||
|
|
||||||
|
def _get_curr_static_group_config(self, multicast_ip_address):
|
||||||
|
sources = None
|
||||||
|
names = None
|
||||||
|
igmp_snooping_groups_config = self._show_igmp_snooping_groups_config(multicast_ip_address)
|
||||||
|
if igmp_snooping_groups_config is not None:
|
||||||
|
igmp_snooping_groups_config = igmp_snooping_groups_config[0]
|
||||||
|
snooping_group_information = igmp_snooping_groups_config.get('Snooping group '
|
||||||
|
'information for VLAN %d and group '
|
||||||
|
'%s' % (self._required_config['vlan_id'],
|
||||||
|
multicast_ip_address))
|
||||||
|
if snooping_group_information is not None:
|
||||||
|
if len(snooping_group_information) == 1:
|
||||||
|
names = snooping_group_information[0].get('V1/V2 Receiver Ports')
|
||||||
|
elif len(snooping_group_information) == 2:
|
||||||
|
sources_dict = dict()
|
||||||
|
v3_receiver_ports = snooping_group_information[1].get('V3 Receiver Ports')
|
||||||
|
ports_number = v3_receiver_ports[0].get('Port Number')
|
||||||
|
sources = v3_receiver_ports[0].get('Include sources')
|
||||||
|
if isinstance(ports_number, list):
|
||||||
|
i = 0
|
||||||
|
for port_number in ports_number:
|
||||||
|
sources_dict[port_number] = sources[i]
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
sources_dict[ports_number] = sources
|
||||||
|
names = snooping_group_information[0].get('V1/V2 Receiver Ports')
|
||||||
|
sources = sources_dict
|
||||||
|
|
||||||
|
return {'sources': sources,
|
||||||
|
'names': names}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _set_igmp_config(self, igmp_vlan_config):
|
||||||
|
igmp_vlan_config = igmp_vlan_config[0]
|
||||||
|
if not igmp_vlan_config:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._current_config['state'] = igmp_vlan_config.get('message 1')
|
||||||
|
if "enabled" in self._current_config['state']:
|
||||||
|
self._current_config['state'] = "enabled"
|
||||||
|
elif "disabled" in self._current_config['state']:
|
||||||
|
self._current_config['state'] = "disabled"
|
||||||
|
|
||||||
|
mrouter_port = igmp_vlan_config.get('mrouter static port list')
|
||||||
|
self._current_config['mrouter'] = dict(self._get_curr_mrouter_config(mrouter_port))
|
||||||
|
|
||||||
|
querier_config = igmp_vlan_config.get('message 3')
|
||||||
|
self._current_config['querier'] = dict(self._get_curr_querier_config(querier_config))
|
||||||
|
|
||||||
|
version = igmp_vlan_config.get('message 2')
|
||||||
|
self._current_config['version'] = self._get_curr_version(version)
|
||||||
|
|
||||||
|
req_static_groups = self._required_config.get('static_groups')
|
||||||
|
if req_static_groups is not None:
|
||||||
|
static_groups = self._current_config['static_groups'] = dict()
|
||||||
|
for static_group in req_static_groups:
|
||||||
|
static_group_config = self._get_curr_static_group_config(static_group['multicast_ip_address'])
|
||||||
|
static_groups[static_group['multicast_ip_address']] = static_group_config
|
||||||
|
|
||||||
|
def _show_igmp_vlan(self):
|
||||||
|
cmd = ("show ip igmp snooping vlan %d" % self._required_config['vlan_id'])
|
||||||
|
return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)
|
||||||
|
|
||||||
|
def _show_igmp_querier_config(self):
|
||||||
|
cmd = ("show ip igmp snooping querier vlan %d " % self._required_config['vlan_id'])
|
||||||
|
return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)
|
||||||
|
|
||||||
|
def _show_igmp_snooping_groups_config(self, multicast_ip_address):
|
||||||
|
cmd = ("show ip igmp snooping groups vlan %d group %s" % (self._required_config['vlan_id'],
|
||||||
|
multicast_ip_address))
|
||||||
|
return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)
|
||||||
|
|
||||||
|
def load_current_config(self):
|
||||||
|
self._current_config = dict()
|
||||||
|
igmp_vlan_config = self._show_igmp_vlan()
|
||||||
|
if igmp_vlan_config:
|
||||||
|
self._set_igmp_config(igmp_vlan_config)
|
||||||
|
|
||||||
|
def generate_commands(self):
|
||||||
|
req_state = self._required_config.get('state', 'enabled')
|
||||||
|
self._generate_igmp_vlan_cmds(req_state)
|
||||||
|
|
||||||
|
_mrouter = self._required_config.get('mrouter')
|
||||||
|
if _mrouter is not None:
|
||||||
|
self._generate_igmp_mrouter_cmds(_mrouter)
|
||||||
|
|
||||||
|
_querier = self._required_config.get('querier')
|
||||||
|
if _querier is not None:
|
||||||
|
req_querier_state = _querier.get('state', 'enabled')
|
||||||
|
self._generate_igmp_querier_cmds(req_querier_state)
|
||||||
|
|
||||||
|
req_querier_interval = _querier.get('interval')
|
||||||
|
if req_querier_interval is not None:
|
||||||
|
self._gen_querier_attr_commands("interval", req_querier_interval, "query-interval")
|
||||||
|
|
||||||
|
req_querier_address = _querier.get('address')
|
||||||
|
if req_querier_address is not None:
|
||||||
|
self._gen_querier_attr_commands("address", req_querier_address, "address")
|
||||||
|
|
||||||
|
_version = self._required_config.get('version')
|
||||||
|
if _version is not None:
|
||||||
|
self._generate_igmp_version_cmds(_version)
|
||||||
|
|
||||||
|
_static_groups = self._required_config.get('static_groups')
|
||||||
|
if _static_groups is not None:
|
||||||
|
for static_group in _static_groups:
|
||||||
|
self._generate_igmp_static_groups_cmd(static_group)
|
||||||
|
|
||||||
|
def _add_igmp_vlan_commands(self, req_state):
|
||||||
|
if req_state == 'enabled':
|
||||||
|
igmp_vlan_cmd = 'vlan %d ip igmp snooping' % self._required_config['vlan_id']
|
||||||
|
else:
|
||||||
|
igmp_vlan_cmd = 'vlan %d no ip igmp snooping' % self._required_config['vlan_id']
|
||||||
|
|
||||||
|
self._commands.append(igmp_vlan_cmd)
|
||||||
|
|
||||||
|
def _generate_igmp_vlan_cmds(self, req_state):
|
||||||
|
curr_state = self._current_config.get('state')
|
||||||
|
if curr_state != req_state:
|
||||||
|
self._add_igmp_vlan_commands(req_state)
|
||||||
|
|
||||||
|
def _gen_querier_attr_commands(self, attr_name, req_attr_value, attr_cmd_name):
|
||||||
|
_curr_querier = self._current_config.get('querier')
|
||||||
|
curr_querier_val = _curr_querier.get(attr_name)
|
||||||
|
if req_attr_value != curr_querier_val:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping querier %s %s' % (self._required_config['vlan_id'],
|
||||||
|
attr_cmd_name, req_attr_value))
|
||||||
|
|
||||||
|
def _add_querier_commands(self, req_querier_state):
|
||||||
|
if req_querier_state == 'enabled':
|
||||||
|
self._commands.append('vlan %d ip igmp snooping querier' % self._required_config['vlan_id'])
|
||||||
|
elif req_querier_state == 'disabled':
|
||||||
|
self._commands.append('vlan %d no ip igmp snooping querier' % (
|
||||||
|
self._required_config['vlan_id']))
|
||||||
|
|
||||||
|
def _generate_igmp_querier_cmds(self, req_querier_state):
|
||||||
|
_curr_querier = self._current_config.get('querier')
|
||||||
|
curr_querier_state = _curr_querier.get('state')
|
||||||
|
if req_querier_state != curr_querier_state:
|
||||||
|
self._add_querier_commands(req_querier_state)
|
||||||
|
|
||||||
|
def _generate_igmp_version_cmds(self, version):
|
||||||
|
_curr_version = self._current_config.get('version')
|
||||||
|
if version != _curr_version:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping version %s' % (
|
||||||
|
self._required_config['vlan_id'], version[1]))
|
||||||
|
|
||||||
|
def _add_mrouter_commands(self, req_mrouter, curr_mrouter):
|
||||||
|
curr_state = curr_mrouter.get('state')
|
||||||
|
curr_interface = curr_mrouter.get('name')
|
||||||
|
req_state = req_mrouter.get('state')
|
||||||
|
req_interface = req_mrouter.get('name')
|
||||||
|
mrouter_interface = req_interface.replace("Eth", "ethernet ")
|
||||||
|
if curr_state == 'enabled' and req_state == 'disabled':
|
||||||
|
self._commands.append('vlan %d no ip igmp snooping mrouter interface '
|
||||||
|
'%s' % (self._required_config['vlan_id'], mrouter_interface))
|
||||||
|
elif curr_state == 'disabled' and req_state == 'enabled':
|
||||||
|
self._commands.append('vlan %d ip igmp snooping mrouter interface '
|
||||||
|
'%s' % (self._required_config['vlan_id'], mrouter_interface))
|
||||||
|
elif req_state == 'enabled' and curr_state == 'enabled' and req_interface != curr_interface:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping mrouter interface '
|
||||||
|
'%s' % (self._required_config['vlan_id'], mrouter_interface))
|
||||||
|
|
||||||
|
def _generate_igmp_mrouter_cmds(self, req_mrouter):
|
||||||
|
curr_mrouter = self._current_config.get('mrouter')
|
||||||
|
if curr_mrouter != req_mrouter:
|
||||||
|
self._add_mrouter_commands(req_mrouter, curr_mrouter)
|
||||||
|
|
||||||
|
def _add_igmp_static_groups_cmd(self, req_name, req_multicast_ip_address, curr_names):
|
||||||
|
if curr_names is None:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping static-group %s interface %s' % (
|
||||||
|
self._required_config['vlan_id'], req_multicast_ip_address, req_name.replace('Eth', 'ethernet ')))
|
||||||
|
elif req_name.replace('E', 'e') not in curr_names:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping static-group %s interface %s' % (
|
||||||
|
self._required_config['vlan_id'], req_multicast_ip_address, req_name.replace('Eth', 'ethernet ')))
|
||||||
|
|
||||||
|
def _add_igmp_static_groups_sources_cmd(self, req_sources, req_name, req_multicast_ip_address, curr_sources):
|
||||||
|
if curr_sources is None:
|
||||||
|
for source in req_sources:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping static-group %s interface %s source %s' % (
|
||||||
|
self._required_config['vlan_id'], req_multicast_ip_address, req_name.replace('Eth', 'ethernet '),
|
||||||
|
source))
|
||||||
|
else:
|
||||||
|
curr_sources = curr_sources.get(req_name.replace('E', 'e'))
|
||||||
|
if curr_sources is None:
|
||||||
|
curr_sources = set([])
|
||||||
|
else:
|
||||||
|
curr_sources = set(x.strip() for x in curr_sources.split(','))
|
||||||
|
sources_to_add = set(req_sources) - set(curr_sources)
|
||||||
|
sources_to_remove = set(curr_sources) - set(req_sources)
|
||||||
|
if len(sources_to_add) != 0:
|
||||||
|
for source in sources_to_add:
|
||||||
|
self._commands.append('vlan %d ip igmp snooping static-group %s interface %s source %s' % (
|
||||||
|
self._required_config['vlan_id'], req_multicast_ip_address,
|
||||||
|
req_name.replace('Eth', 'ethernet '), source))
|
||||||
|
if len(sources_to_remove) != 0:
|
||||||
|
for source in sources_to_remove:
|
||||||
|
self._commands.append('vlan %d no ip igmp snooping static-group %s interface %s source %s' % (
|
||||||
|
self._required_config['vlan_id'], req_multicast_ip_address,
|
||||||
|
req_name.replace('Eth', 'ethernet '),
|
||||||
|
source))
|
||||||
|
|
||||||
|
def _generate_igmp_static_groups_cmd(self, static_group):
|
||||||
|
req_multicast_ip_address = static_group.get('multicast_ip_address')
|
||||||
|
req_name = static_group.get('name')
|
||||||
|
req_sources = static_group.get('sources')
|
||||||
|
curr_static_groups = self._current_config.get('static_groups')
|
||||||
|
curr_static_group = curr_static_groups.get(req_multicast_ip_address)
|
||||||
|
curr_names = None
|
||||||
|
curr_sources = None
|
||||||
|
if curr_static_group is not None:
|
||||||
|
curr_names = curr_static_group.get('names')
|
||||||
|
curr_sources = curr_static_group.get('sources')
|
||||||
|
|
||||||
|
self._add_igmp_static_groups_cmd(req_name, req_multicast_ip_address, curr_names)
|
||||||
|
if req_sources is not None:
|
||||||
|
self._add_igmp_static_groups_sources_cmd(req_sources, req_name, req_multicast_ip_address, curr_sources)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" main entry point for module execution
|
||||||
|
"""
|
||||||
|
OnyxIgmpVlanModule.main()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,10 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"mrouter static port list": "none",
|
||||||
|
"mrouter dynamic port list": "none",
|
||||||
|
"header": "Vlan 10 configuration parameters",
|
||||||
|
"message 1": "IGMP snooping is disabled",
|
||||||
|
"message 2": "IGMP version is V3",
|
||||||
|
"message 3": "Snooping switch is acting as Non-Querier"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,30 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Snooping group information for VLAN 10 and group 224.5.5.1": [
|
||||||
|
{
|
||||||
|
"Group flag": "St",
|
||||||
|
"Filter Mode": "EXCLUDE",
|
||||||
|
"V1/V2 Receiver Ports": "eth1/1, eth1/2",
|
||||||
|
"Exclude sources": "None"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"V3 Receiver Ports": [
|
||||||
|
{
|
||||||
|
"Exclude sources": [
|
||||||
|
"None",
|
||||||
|
"None"
|
||||||
|
],
|
||||||
|
"Include sources": [
|
||||||
|
"1.1.1.1, 1.1.1.2",
|
||||||
|
"1.1.1.3"
|
||||||
|
],
|
||||||
|
"Port Number": [
|
||||||
|
"eth1/1",
|
||||||
|
"eth1/2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Snooping querier information for VLAN 10": [
|
||||||
|
{
|
||||||
|
"Lines": [
|
||||||
|
"IGMP Querier Not Present"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Response interval": "100",
|
||||||
|
"Elected querier IP address": "0.0.0.0",
|
||||||
|
"Group membership interval": "1",
|
||||||
|
"Robustness": "2",
|
||||||
|
"Configured querier IP address": "-",
|
||||||
|
"Query interval": "125",
|
||||||
|
"Version": "3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
190
test/units/modules/network/onyx/test_onyx_igmp_vlan.py
Normal file
190
test/units/modules/network/onyx/test_onyx_igmp_vlan.py
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
#
|
||||||
|
# Copyright: Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from units.compat.mock import patch
|
||||||
|
from ansible.modules.network.onyx import onyx_igmp_vlan
|
||||||
|
from units.modules.utils import set_module_args
|
||||||
|
from .onyx_module import TestOnyxModule, load_fixture
|
||||||
|
|
||||||
|
|
||||||
|
class TestOnyxIgmpVlan(TestOnyxModule):
|
||||||
|
|
||||||
|
module = onyx_igmp_vlan
|
||||||
|
enabled = False
|
||||||
|
mrouter_state = False
|
||||||
|
querier_state = False
|
||||||
|
static_groups_enabled = False
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.enabled = False
|
||||||
|
super(TestOnyxIgmpVlan, self).setUp()
|
||||||
|
self.mock_get_igmp_config = patch.object(
|
||||||
|
onyx_igmp_vlan.OnyxIgmpVlanModule, "_show_igmp_vlan")
|
||||||
|
self.get_igmp_config = self.mock_get_igmp_config.start()
|
||||||
|
|
||||||
|
self.mock_load_config = patch(
|
||||||
|
'ansible.module_utils.network.onyx.onyx.load_config')
|
||||||
|
self.load_config = self.mock_load_config.start()
|
||||||
|
|
||||||
|
self.mock_get_igmp_guerier_config = patch.object(
|
||||||
|
onyx_igmp_vlan.OnyxIgmpVlanModule, "_show_igmp_querier_config")
|
||||||
|
self.get_igmp_guerier_config = self.mock_get_igmp_guerier_config.start()
|
||||||
|
|
||||||
|
self.mock_get_igmp_static_groups_config = patch.object(
|
||||||
|
onyx_igmp_vlan.OnyxIgmpVlanModule, "_show_igmp_snooping_groups_config")
|
||||||
|
self.get_igmp_static_groups_config = self.mock_get_igmp_static_groups_config.start()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(TestOnyxIgmpVlan, self).tearDown()
|
||||||
|
self.mock_get_igmp_config.stop()
|
||||||
|
self.mock_load_config.stop()
|
||||||
|
self.mock_get_igmp_guerier_config.stop()
|
||||||
|
self.mock_get_igmp_static_groups_config.stop()
|
||||||
|
|
||||||
|
def load_fixtures(self, commands=None, transport='cli'):
|
||||||
|
igmp_vlan_config_file = 'onyx_show_ip_igmp_snooping.cfg'
|
||||||
|
igmp_querier_config_file = 'onyx_show_ip_igmp_snooping_querier.cfg'
|
||||||
|
igmp_static_groups_file = 'onyx_show_ip_igmp_snooping_groups.cfg'
|
||||||
|
igmp_vlan_data = load_fixture(igmp_vlan_config_file)
|
||||||
|
igmp_querier_data = load_fixture(igmp_querier_config_file)
|
||||||
|
igmp_static_groups_data = None
|
||||||
|
if self.enabled:
|
||||||
|
igmp_vlan_data[0]['message 1'] = 'IGMP snooping is enabled'
|
||||||
|
|
||||||
|
if self.querier_state:
|
||||||
|
igmp_vlan_data[0]['message 3'] = 'Snooping switch is acting as Querier'
|
||||||
|
|
||||||
|
if self.mrouter_state:
|
||||||
|
igmp_vlan_data[0]['mrouter static port list'] = 'Eth1/1'
|
||||||
|
|
||||||
|
if self.static_groups_enabled:
|
||||||
|
igmp_static_groups_data = load_fixture(igmp_static_groups_file)
|
||||||
|
|
||||||
|
self.get_igmp_config.return_value = igmp_vlan_data
|
||||||
|
self.get_igmp_guerier_config = igmp_querier_data
|
||||||
|
self.get_igmp_static_groups_config = igmp_static_groups_data
|
||||||
|
self.load_config.return_value = None
|
||||||
|
|
||||||
|
def test_igmp_disabled_no_change(self):
|
||||||
|
set_module_args(dict(state='disabled', vlan_id=10))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_disabled_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(state='disabled', vlan_id=10))
|
||||||
|
commands = ['vlan 10 no ip igmp snooping']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_enabled_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(state='enabled', vlan_id=10))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_enabled_with_change(self):
|
||||||
|
set_module_args(dict(state='enabled', vlan_id=10))
|
||||||
|
commands = ['vlan 10 ip igmp snooping']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_mrouter_disabled_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, mrouter=dict(state='disabled', name='Eth1/1')))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_mrouter_disabled_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.mrouter_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, mrouter=dict(state='disabled', name='Eth1/1')))
|
||||||
|
commands = ['vlan 10 no ip igmp snooping mrouter interface ethernet 1/1']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_mrouter_enabled_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.mrouter_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, mrouter=dict(state='enabled', name='Eth1/1')))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_mrouter_enabled_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, mrouter=dict(state='enabled', name='Eth1/1')))
|
||||||
|
commands = ['vlan 10 ip igmp snooping mrouter interface ethernet 1/1']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_mrouter_enabled_withinterface_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.mrouter_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, mrouter=dict(state='enabled', name='Eth1/2')))
|
||||||
|
commands = ['vlan 10 ip igmp snooping mrouter interface ethernet 1/2']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_querier_disabled_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, querier=dict(state='disabled')))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_querier_disabled_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.querier_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, querier=dict(state='disabled')))
|
||||||
|
commands = ['vlan 10 no ip igmp snooping querier']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_querier_enabled_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.querier_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, querier=dict(state='enabled')))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_querier_enabled_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, querier=dict(state='enabled')))
|
||||||
|
commands = ['vlan 10 ip igmp snooping querier']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_querier_attr_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.querier_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, querier=dict(state='enabled', interval=125, address='-')))
|
||||||
|
self.execute_module(changed=True)
|
||||||
|
|
||||||
|
def test_igmp_querier_attr_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.querier_state = True
|
||||||
|
set_module_args(dict(vlan_id=10, querier=dict(state='enabled', interval=127, address='10.10.10.1')))
|
||||||
|
commands = ['vlan 10 ip igmp snooping querier query-interval 127',
|
||||||
|
'vlan 10 ip igmp snooping querier address 10.10.10.1']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_version_no_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, version='V3'))
|
||||||
|
self.execute_module(changed=False)
|
||||||
|
|
||||||
|
def test_igmp_version_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, version='V2'))
|
||||||
|
commands = ['vlan 10 ip igmp snooping version 2']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_static_groups_multicast_ip_address_not_configured(self):
|
||||||
|
self.enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, static_groups=[dict(multicast_ip_address='224.5.5.2', name='Eth1/1',
|
||||||
|
sources=["1.1.1.2", "1.1.1.3"])]))
|
||||||
|
commands = ['vlan 10 ip igmp snooping static-group 224.5.5.2 interface ethernet 1/1',
|
||||||
|
'vlan 10 ip igmp snooping static-group 224.5.5.2 interface ethernet 1/1 source 1.1.1.2',
|
||||||
|
'vlan 10 ip igmp snooping static-group 224.5.5.2 interface ethernet 1/1 source 1.1.1.3']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
||||||
|
|
||||||
|
def test_igmp_static_groups_multicast_ip_address_configured_with_change(self):
|
||||||
|
self.enabled = True
|
||||||
|
self.static_groups_enabled = True
|
||||||
|
set_module_args(dict(vlan_id=10, static_groups=[dict(multicast_ip_address='224.5.5.1', name='Eth1/3',
|
||||||
|
sources=["1.1.1.1", "1.1.1.2"])]))
|
||||||
|
commands = ['vlan 10 ip igmp snooping static-group 224.5.5.1 interface ethernet 1/3',
|
||||||
|
'vlan 10 ip igmp snooping static-group 224.5.5.1 interface ethernet 1/3 source 1.1.1.1',
|
||||||
|
'vlan 10 ip igmp snooping static-group 224.5.5.1 interface ethernet 1/3 source 1.1.1.2']
|
||||||
|
self.execute_module(changed=True, commands=commands)
|
Loading…
Reference in a new issue