def get_interfaces_dict(module): """Gets all active interfaces on a given switch """ try: body = execute_show_command('show interface', module)[0] except IndexError: return {} interfaces = { 'ethernet': [], 'svi': [], 'loopback': [], 'management': [], 'portchannel': [], 'nve': [], 'unknown': [] } if body: interface_list = body['TABLE_interface']['ROW_interface'] for index in interface_list: intf = index['interface'] intf_type = get_interface_type(intf) interfaces[intf_type].append(intf) return interfaces
def interface_is_portchannel(name, module): """Checks to see if an interface is part of portchannel bundle Args: interface (str): full name of interface, i.e. Ethernet1/1 Returns: True/False based on if interface is a member of a portchannel bundle """ intf_type = get_interface_type(name) if intf_type == 'ethernet': command = 'show interface {0} | json'.format(name) try: body = run_commands(module, [command])[0] interface_table = body['TABLE_interface']['ROW_interface'] except (KeyError, AttributeError, IndexError): interface_table = None if interface_table: state = interface_table.get('eth_bundle') if state: return True else: return False return False
def get_interface_mode(name, module): """Gets current mode of interface: layer2 or layer3 Args: device (Device): This is the device object of an NX-API enabled device using the Device class within device.py interface (string): full name of interface, i.e. Ethernet1/1, loopback10, port-channel20, vlan20 Returns: str: 'layer2' or 'layer3' """ command = 'show interface {0} | json'.format(name) intf_type = get_interface_type(name) mode = 'unknown' interface_table = {} try: body = run_commands(module, [command])[0] interface_table = body['TABLE_interface']['ROW_interface'] except (KeyError, AttributeError, IndexError): return mode if interface_table: # HACK FOR NOW if intf_type in ['ethernet', 'portchannel']: mode = str(interface_table.get('eth_mode', 'layer3')) if mode in ['access', 'trunk']: mode = 'layer2' if mode == 'routed': mode = 'layer3' elif intf_type == 'loopback' or intf_type == 'svi': mode = 'layer3' return mode
def main(): argument_spec = dict(group=dict(required=True, type='str'), interface=dict(required=True), interval=dict(required=False, type='str'), priority=dict(required=False, type='str'), preempt=dict(required=False, type='bool'), vip=dict(required=False, type='str'), admin_state=dict( required=False, type='str', choices=['shutdown', 'no shutdown', 'default'], default='shutdown'), authentication=dict(required=False, type='str'), state=dict(choices=['absent', 'present'], required=False, default='present')) argument_spec.update(nxos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() results = {'changed': False, 'commands': [], 'warnings': warnings} state = module.params['state'] interface = module.params['interface'].lower() group = module.params['group'] priority = module.params['priority'] interval = module.params['interval'] preempt = module.params['preempt'] vip = module.params['vip'] authentication = module.params['authentication'] admin_state = module.params['admin_state'] device_info = get_capabilities(module) network_api = device_info.get('network_api', 'nxapi') if state == 'present' and not vip: module.fail_json(msg='the "vip" param is required when state=present') intf_type = get_interface_type(interface) if (intf_type != 'ethernet' and network_api == 'cliconf'): if is_default(interface, module) == 'DNE': module.fail_json(msg='That interface does not exist yet. Create ' 'it first.', interface=interface) if intf_type == 'loopback': module.fail_json(msg="Loopback interfaces don't support VRRP.", interface=interface) mode, name = get_interface_mode(interface, intf_type, module) if mode == 'layer2': module.fail_json(msg='That interface is a layer2 port.\nMake it ' 'a layer 3 port first.', interface=interface) args = dict(group=group, priority=priority, preempt=preempt, vip=vip, authentication=authentication, interval=interval, admin_state=admin_state) proposed = dict((k, v) for k, v in args.items() if v is not None) existing = get_existing_vrrp(interface, group, module, name) commands = [] if state == 'present': delta = dict(set(proposed.items()).difference(existing.items())) if delta: command = get_commands_config_vrrp(delta, existing, group) if command: commands.append(command) elif state == 'absent': if existing: commands.append(['no vrrp {0}'.format(group)]) if commands: commands.insert(0, ['interface {0}'.format(interface)]) commands = flatten_list(commands) results['commands'] = commands results['changed'] = True if not module.check_mode: load_config(module, commands) if 'configure' in commands: commands.pop(0) module.exit_json(**results)
def map_config_to_obj(want, module): objs = list() for w in want: obj = dict(name=None, description=None, admin_state=None, speed=None, mtu=None, mode=None, duplex=None, interface_type=None, ip_forward=None, fabric_forwarding_anycast_gateway=None) if not w['name']: return obj command = 'show interface {0}'.format(w['name']) try: body = execute_show_command(command, module)[0] except IndexError: return list() if body: try: interface_table = body['TABLE_interface']['ROW_interface'] except (KeyError, TypeError): return list() if interface_table: if interface_table.get('eth_mode') == 'fex-fabric': module.fail_json( msg= 'nxos_interface does not support interfaces with mode "fex-fabric"' ) intf_type = get_interface_type(w['name']) if intf_type in ['portchannel', 'ethernet']: mode = interface_table.get('eth_mode') if mode in ('access', 'trunk', 'dot1q-tunnel'): obj['mode'] = 'layer2' elif mode in ('routed', 'layer3'): obj['mode'] = 'layer3' else: obj['mode'] = 'layer3' if intf_type == 'ethernet': obj['name'] = normalize_interface( interface_table.get('interface')) obj['admin_state'] = interface_table.get('admin_state') obj['description'] = interface_table.get('desc') obj['mtu'] = interface_table.get('eth_mtu') obj['duplex'] = interface_table.get('eth_duplex') command = 'show run interface {0}'.format(obj['name']) body = execute_show_command(command, module)[0] speed_match = re.search(r'speed (\d+)', body) if speed_match is None: obj['speed'] = 'auto' else: obj['speed'] = speed_match.group(1) duplex_match = re.search(r'duplex (\S+)', body) if duplex_match is None: obj['duplex'] = 'auto' else: obj['duplex'] = duplex_match.group(1) if 'ip forward' in body: obj['ip_forward'] = 'enable' else: obj['ip_forward'] = 'disable' elif intf_type == 'svi': obj['name'] = normalize_interface( interface_table.get('interface')) attributes = get_vlan_interface_attributes( obj['name'], intf_type, module) obj['admin_state'] = str( attributes.get('admin_state', 'nxapibug')) obj['description'] = str( attributes.get('description', 'nxapi_bug')) obj['mtu'] = interface_table.get('svi_mtu') command = 'show run interface {0}'.format(obj['name']) body = execute_show_command(command, module)[0] if 'ip forward' in body: obj['ip_forward'] = 'enable' else: obj['ip_forward'] = 'disable' if 'fabric forwarding mode anycast-gateway' in body: obj['fabric_forwarding_anycast_gateway'] = True else: obj['fabric_forwarding_anycast_gateway'] = False elif intf_type in ('loopback', 'management', 'nve'): obj['name'] = normalize_interface( interface_table.get('interface')) obj['admin_state'] = interface_table.get('admin_state') if obj['admin_state'] is None and intf_type == 'loopback': # Some platforms don't have the 'admin_state' key. # For loopback interfaces it's safe to use the # 'state' key instead. obj['admin_state'] = interface_table.get('state') obj['description'] = interface_table.get('desc') elif intf_type == 'portchannel': obj['name'] = normalize_interface( interface_table.get('interface')) obj['admin_state'] = interface_table.get('admin_state') obj['description'] = interface_table.get('desc') obj['mtu'] = interface_table.get('eth_mtu') if obj['admin_state'] is None: # Some nxos platforms do not have the 'admin_state' key. # Use the 'state_rsn_desc' key instead to determine the # admin state of the interface. state_description = interface_table.get('state_rsn_desc') if state_description == 'Administratively down': obj['admin_state'] = 'down' elif state_description is not None: obj['admin_state'] = 'up' objs.append(obj) return objs
def map_obj_to_commands(updates, module): commands = list() commands2 = list() want, have = updates args = ('speed', 'description', 'duplex', 'mtu') for w in want: name = w['name'] mode = w['mode'] ip_forward = w['ip_forward'] fabric_forwarding_anycast_gateway = w[ 'fabric_forwarding_anycast_gateway'] admin_state = w['admin_state'] state = w['state'] interface_type = w['interface_type'] del w['state'] if name: w['interface_type'] = None if interface_type: obj_in_have = {} if state in ('present', 'default'): module.fail_json( msg= 'The interface_type param can be used only with state absent.' ) else: obj_in_have = search_obj_in_list(name, have) is_default = is_default_interface(name, module) if name: interface = 'interface ' + name if state == 'absent': if obj_in_have: commands.append('no interface {0}'.format(name)) elif interface_type and not obj_in_have: intfs = get_interfaces_dict(module)[interface_type] cmds = get_interface_type_removed_cmds(intfs) commands.extend(cmds) elif state == 'present': if obj_in_have: # Don't run switchport command for loopback and svi interfaces if get_interface_type(name) in ('ethernet', 'portchannel'): if mode == 'layer2' and mode != obj_in_have.get('mode'): add_command_to_interface(interface, 'switchport', commands) elif mode == 'layer3' and mode != obj_in_have.get('mode'): add_command_to_interface(interface, 'no switchport', commands) if admin_state == 'up' and admin_state != obj_in_have.get( 'admin_state'): add_command_to_interface(interface, 'no shutdown', commands) elif admin_state == 'down' and admin_state != obj_in_have.get( 'admin_state'): add_command_to_interface(interface, 'shutdown', commands) if ip_forward == 'enable' and ip_forward != obj_in_have.get( 'ip_forward'): add_command_to_interface(interface, 'ip forward', commands) elif ip_forward == 'disable' and ip_forward != obj_in_have.get( 'ip forward'): add_command_to_interface(interface, 'no ip forward', commands) if (fabric_forwarding_anycast_gateway is True and obj_in_have.get('fabric_forwarding_anycast_gateway') is False): add_command_to_interface( interface, 'fabric forwarding mode anycast-gateway', commands) elif (fabric_forwarding_anycast_gateway is False and obj_in_have.get('fabric_forwarding_anycast_gateway') is True): add_command_to_interface( interface, 'no fabric forwarding mode anycast-gateway', commands) for item in args: candidate = w.get(item) if candidate and candidate != obj_in_have.get(item): cmd = item + ' ' + str(candidate) add_command_to_interface(interface, cmd, commands) if name and get_interface_type(name) == 'ethernet': if mode != obj_in_have.get('mode'): admin_state = w.get('admin_state') or obj_in_have.get( 'admin_state') if admin_state: c1 = 'interface {0}'.format( normalize_interface(w['name'])) c2 = get_admin_state(admin_state) commands2.append(c1) commands2.append(c2) else: commands.append(interface) # Don't run switchport command for loopback and svi interfaces if get_interface_type(name) in ('ethernet', 'portchannel'): if mode == 'layer2': commands.append('switchport') elif mode == 'layer3': commands.append('no switchport') if admin_state == 'up': commands.append('no shutdown') elif admin_state == 'down': commands.append('shutdown') if ip_forward == 'enable': commands.append('ip forward') elif ip_forward == 'disable': commands.append('no ip forward') if fabric_forwarding_anycast_gateway is True: commands.append('fabric forwarding mode anycast-gateway') elif fabric_forwarding_anycast_gateway is False: commands.append( 'no fabric forwarding mode anycast-gateway') for item in args: candidate = w.get(item) if candidate: commands.append(item + ' ' + str(candidate)) elif state == 'default': if is_default is False: commands.append('default interface {0}'.format(name)) elif is_default == 'DNE': module.exit_json( msg='interface you are trying to default does not exist') return commands, commands2
def map_obj_to_commands(updates, module): commands = list() want, have = updates state = module.params['state'] purge = module.params['purge'] args = ('rd', 'description', 'vni') for w in want: name = w['name'] admin_state = w['admin_state'] vni = w['vni'] interfaces = w.get('interfaces') or [] if purge: state = "absent" else: state = w['state'] del w['state'] obj_in_have = search_obj_in_list(name, have) if state == 'absent' and obj_in_have: commands.append('no vrf context {0}'.format(name)) elif state == 'present': if not obj_in_have: commands.append('vrf context {0}'.format(name)) for item in args: candidate = w.get(item) if candidate and candidate != 'default': cmd = item + ' ' + str(candidate) commands.append(cmd) if admin_state == 'up': commands.append('no shutdown') elif admin_state == 'down': commands.append('shutdown') commands.append('exit') if interfaces and interfaces[0] != 'default': for i in interfaces: commands.append('interface {0}'.format(i)) if get_interface_type(i) in ('ethernet', 'portchannel'): commands.append('no switchport') commands.append('vrf member {0}'.format(name)) else: # If vni is already configured on vrf, unconfigure it first. if vni: if obj_in_have.get( 'vni') and vni != obj_in_have.get('vni'): commands.append('no vni {0}'.format( obj_in_have.get('vni'))) for item in args: candidate = w.get(item) if candidate == 'default': if obj_in_have.get(item): cmd = 'no ' + item + ' ' + obj_in_have.get(item) commands.append(cmd) elif candidate and candidate != obj_in_have.get(item): cmd = item + ' ' + str(candidate) commands.append(cmd) if admin_state and admin_state != obj_in_have.get( 'admin_state'): if admin_state == 'up': commands.append('no shutdown') elif admin_state == 'down': commands.append('shutdown') if commands: commands.insert(0, 'vrf context {0}'.format(name)) commands.append('exit') if interfaces and interfaces[0] != 'default': if not obj_in_have['interfaces']: for i in interfaces: commands.append('vrf context {0}'.format(name)) commands.append('exit') commands.append('interface {0}'.format(i)) if get_interface_type(i) in ('ethernet', 'portchannel'): commands.append('no switchport') commands.append('vrf member {0}'.format(name)) elif set(interfaces) != set(obj_in_have['interfaces']): missing_interfaces = list( set(interfaces) - set(obj_in_have['interfaces'])) for i in missing_interfaces: commands.append('vrf context {0}'.format(name)) commands.append('exit') commands.append('interface {0}'.format(i)) if get_interface_type(i) in ('ethernet', 'portchannel'): commands.append('no switchport') commands.append('vrf member {0}'.format(name)) superfluous_interfaces = list( set(obj_in_have['interfaces']) - set(interfaces)) for i in superfluous_interfaces: commands.append('vrf context {0}'.format(name)) commands.append('exit') commands.append('interface {0}'.format(i)) if get_interface_type(i) in ('ethernet', 'portchannel'): commands.append('no switchport') commands.append('no vrf member {0}'.format(name)) elif interfaces and interfaces[0] == 'default': if obj_in_have['interfaces']: for i in obj_in_have['interfaces']: commands.append('vrf context {0}'.format(name)) commands.append('exit') commands.append('interface {0}'.format(i)) if get_interface_type(i) in ('ethernet', 'portchannel'): commands.append('no switchport') commands.append('no vrf member {0}'.format(name)) if purge: existing = get_existing_vrfs(module) if existing: for h in existing: if h['name'] in ('default', 'management'): pass else: obj_in_want = search_obj_in_list(h['name'], want) if not obj_in_want: commands.append('no vrf context {0}'.format(h['name'])) return commands
def main(): argument_spec = dict( interface=dict(type='str', required=True), sparse=dict(type='bool', default=False), dr_prio=dict(type='str'), hello_auth_key=dict(type='str'), hello_interval=dict(type='int'), jp_policy_out=dict(type='str'), jp_policy_in=dict(type='str'), jp_type_out=dict(type='str', choices=['prefix', 'routemap']), jp_type_in=dict(type='str', choices=['prefix', 'routemap']), bfd=dict(type='str', choices=['enable', 'disable', 'default']), border=dict(type='bool', default=False), neighbor_policy=dict(type='str'), neighbor_type=dict(type='str', choices=['prefix', 'routemap']), state=dict(type='str', default='present', choices=['absent', 'default', 'present']), ) argument_spec.update(nxos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() results = {'changed': False, 'commands': [], 'warnings': warnings} state = module.params['state'] interface = module.params['interface'] jp_type_in = module.params['jp_type_in'] jp_type_out = module.params['jp_type_out'] jp_policy_in = module.params['jp_policy_in'] jp_policy_out = module.params['jp_policy_out'] neighbor_policy = module.params['neighbor_policy'] neighbor_type = module.params['neighbor_type'] intf_type = get_interface_type(interface) if get_interface_mode(interface, intf_type, module) == 'layer2': module.fail_json(msg='this module only works on Layer 3 interfaces.') if jp_policy_in: if not jp_type_in: module.fail_json( msg='jp_type_in required when using jp_policy_in.') if jp_policy_out: if not jp_type_out: module.fail_json( msg='jp_type_out required when using jp_policy_out.') if neighbor_policy: if not neighbor_type: module.fail_json( msg='neighbor_type required when using neighbor_policy.') get_existing = get_pim_interface(module, interface) existing, jp_bidir, isauth = local_existing(get_existing) args = PARAM_TO_COMMAND_KEYMAP.keys() proposed = dict((k, v) for k, v in module.params.items() if v is not None and k in args) normalize_proposed_values(proposed) delta = dict(set(proposed.items()).difference(existing.items())) commands = [] if state == 'present': if delta: command = config_pim_interface(delta, existing, jp_bidir, isauth) if command: commands.append(command) elif state == 'default' or state == 'absent': defaults = config_pim_interface_defaults(existing, jp_bidir, isauth) if defaults: commands.append(defaults) if commands: commands.insert(0, ['interface {0}'.format(interface)]) cmds = flatten_list(commands) if cmds: results['changed'] = True if not module.check_mode: load_config(module, cmds) if 'configure' in cmds: cmds.pop(0) results['commands'] = cmds module.exit_json(**results)
def main(): argument_spec = dict( vrf=dict(required=True), interface=dict(type='str', required=True), state=dict(default='present', choices=['present', 'absent'], required=False), ) argument_spec.update(nxos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() results = {'changed': False, 'commands': [], 'warnings': warnings} vrf = module.params['vrf'] interface = module.params['interface'].lower() state = module.params['state'] device_info = get_capabilities(module) network_api = device_info.get('network_api', 'nxapi') current_vrfs = get_vrf_list(module) if vrf not in current_vrfs: warnings.append("The VRF is not present/active on the device. " "Use nxos_vrf to fix this.") intf_type = get_interface_type(interface) if (intf_type != 'ethernet' and network_api == 'cliconf'): if is_default(interface, module) == 'DNE': module.fail_json(msg="interface does not exist on switch. Verify " "switch platform or create it first with " "nxos_interface if it's a logical interface") mode = get_interface_mode(interface, intf_type, module) if mode == 'layer2': module.fail_json(msg='Ensure interface is a Layer 3 port before ' 'configuring a VRF on an interface. You can ' 'use nxos_interface') current_vrf = get_interface_info(interface, module) existing = dict(interface=interface, vrf=current_vrf) changed = False if not existing['vrf']: pass elif vrf != existing['vrf'] and state == 'absent': module.fail_json(msg='The VRF you are trying to remove ' 'from the interface does not exist ' 'on that interface.', interface=interface, proposed_vrf=vrf, existing_vrf=existing['vrf']) commands = [] if existing: if state == 'absent': if existing and vrf == existing['vrf']: command = 'no vrf member {0}'.format(vrf) commands.append(command) elif state == 'present': if existing['vrf'] != vrf: command = 'vrf member {0}'.format(vrf) commands.append(command) if commands: commands.insert(0, 'interface {0}'.format(interface)) if commands: if module.check_mode: module.exit_json(changed=True, commands=commands) else: load_config(module, commands) changed = True if 'configure' in commands: commands.pop(0) results['commands'] = commands results['changed'] = changed module.exit_json(**results)
def main(): argument_spec = dict(group=dict(required=True, type='str'), interface=dict(required=True), version=dict(choices=['1', '2'], default='1', required=False), priority=dict(type='str', required=False), preempt=dict(type='str', choices=['disabled', 'enabled'], required=False), vip=dict(type='str', required=False), auth_type=dict(choices=['text', 'md5'], required=False), auth_string=dict(type='str', required=False), state=dict(choices=['absent', 'present'], required=False, default='present')) argument_spec.update(nxos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() results = dict(changed=False, warnings=warnings) interface = module.params['interface'].lower() group = module.params['group'] version = module.params['version'] state = module.params['state'] priority = module.params['priority'] preempt = module.params['preempt'] vip = module.params['vip'] auth_type = module.params['auth_type'] auth_full_string = module.params['auth_string'] auth_enc = '0' auth_string = None if auth_full_string: kstr = auth_full_string.split() if len(kstr) == 2: auth_enc = kstr[0] auth_string = kstr[1] elif len(kstr) == 1: auth_string = kstr[0] else: module.fail_json(msg='Invalid auth_string') if auth_enc != '0' and auth_enc != '7': module.fail_json(msg='Invalid auth_string, only 0 or 7 allowed') device_info = get_capabilities(module) network_api = device_info.get('network_api', 'nxapi') intf_type = get_interface_type(interface) if (intf_type != 'ethernet' and network_api == 'cliconf'): if is_default(interface, module) == 'DNE': module.fail_json(msg='That interface does not exist yet. Create ' 'it first.', interface=interface) if intf_type == 'loopback': module.fail_json(msg="Loopback interfaces don't support HSRP.", interface=interface) mode = get_interface_mode(interface, intf_type, module) if mode == 'layer2': module.fail_json(msg='That interface is a layer2 port.\nMake it ' 'a layer 3 port first.', interface=interface) if auth_type or auth_string: if not (auth_type and auth_string): module.fail_json(msg='When using auth parameters, you need BOTH ' 'auth_type AND auth_string.') args = dict(group=group, version=version, priority=priority, preempt=preempt, vip=vip, auth_type=auth_type, auth_string=auth_string, auth_enc=auth_enc) proposed = dict((k, v) for k, v in args.items() if v is not None) existing = get_hsrp_group(group, interface, module) # This will enforce better practice with md5 and hsrp version. if proposed.get('auth_type', None) == 'md5': if proposed['version'] == '1': module.fail_json(msg="It's recommended to use HSRP v2 " "when auth_type=md5") elif not proposed.get('auth_type', None) and existing: if (proposed['version'] == '1' and existing['auth_type'] == 'md5') and state == 'present': module.fail_json(msg="Existing auth_type is md5. It's recommended " "to use HSRP v2 when using md5") commands = [] if state == 'present': delta = dict(set(proposed.items()).difference(existing.items())) if delta: command = get_commands_config_hsrp(delta, interface, args, existing) commands.extend(command) elif state == 'absent': if existing: command = get_commands_remove_hsrp(group, interface) commands.extend(command) if commands: if module.check_mode: module.exit_json(**results) else: load_config(module, commands) # validate IP if network_api == 'cliconf' and state == 'present': commands.insert(0, 'config t') body = run_commands(module, commands) validate_config(body, vip, module) results['changed'] = True if 'configure' in commands: commands.pop(0) results['commands'] = commands module.exit_json(**results)
def main(): argument_spec = dict(interface=dict(required=True, type='str'), version=dict(required=False, type='str'), startup_query_interval=dict(required=False, type='str'), startup_query_count=dict(required=False, type='str'), robustness=dict(required=False, type='str'), querier_timeout=dict(required=False, type='str'), query_mrt=dict(required=False, type='str'), query_interval=dict(required=False, type='str'), last_member_qrt=dict(required=False, type='str'), last_member_query_count=dict(required=False, type='str'), group_timeout=dict(required=False, type='str'), report_llg=dict(type='bool'), immediate_leave=dict(type='bool'), oif_routemap=dict(required=False, type='str'), oif_prefix=dict(required=False, type='str', removed_in_version='2.10'), oif_source=dict(required=False, type='str', removed_in_version='2.10'), oif_ps=dict(required=False, type='raw'), restart=dict(type='bool', default=False), state=dict(choices=['present', 'absent', 'default'], default='present')) argument_spec.update(nxos_argument_spec) mutually_exclusive = [('oif_ps', 'oif_prefix'), ('oif_ps', 'oif_source'), ('oif_ps', 'oif_routemap'), ('oif_prefix', 'oif_routemap')] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() state = module.params['state'] interface = module.params['interface'] oif_prefix = module.params['oif_prefix'] oif_source = module.params['oif_source'] oif_routemap = module.params['oif_routemap'] oif_ps = module.params['oif_ps'] if oif_source and not oif_prefix: module.fail_json(msg='oif_prefix required when setting oif_source') elif oif_source and oif_prefix: oif_ps = [{'source': oif_source, 'prefix': oif_prefix}] elif not oif_source and oif_prefix: oif_ps = [{'prefix': oif_prefix}] intf_type = get_interface_type(interface) if get_interface_mode(interface, intf_type, module) == 'layer2': module.fail_json(msg='this module only works on Layer 3 interfaces') existing = get_igmp_interface(module, interface) existing_copy = existing.copy() end_state = existing_copy if not existing.get('version'): module.fail_json(msg='pim needs to be enabled on the interface') existing_oif_prefix_source = existing.get('oif_prefix_source') # not json serializable existing.pop('oif_prefix_source') if oif_routemap and existing_oif_prefix_source: module.fail_json(msg='Delete static-oif configurations on this ' 'interface if you want to use a routemap') if oif_ps and existing.get('oif_routemap'): module.fail_json(msg='Delete static-oif route-map configuration ' 'on this interface if you want to config ' 'static entries') args = [ 'version', 'startup_query_interval', 'startup_query_count', 'robustness', 'querier_timeout', 'query_mrt', 'query_interval', 'last_member_qrt', 'last_member_query_count', 'group_timeout', 'report_llg', 'immediate_leave', 'oif_routemap', ] changed = False commands = [] proposed = dict((k, v) for k, v in module.params.items() if v is not None and k in args) CANNOT_ABSENT = [ 'version', 'startup_query_interval', 'startup_query_count', 'robustness', 'querier_timeout', 'query_mrt', 'query_interval', 'last_member_qrt', 'last_member_query_count', 'group_timeout', 'report_llg', 'immediate_leave' ] if state == 'absent': for each in CANNOT_ABSENT: if each in proposed: module.fail_json(msg='only params: oif_prefix, oif_source, ' 'oif_ps, oif_routemap can be used when ' 'state=absent') # delta check for all params except oif_ps delta = dict(set(proposed.items()).difference(existing.items())) if oif_ps: if oif_ps == 'default': delta['oif_ps'] = [] else: delta['oif_ps'] = oif_ps if state == 'present': if delta: command = config_igmp_interface(delta, existing, existing_oif_prefix_source) if command: commands.append(command) elif state == 'default': command = config_default_igmp_interface(existing, delta) if command: commands.append(command) elif state == 'absent': command = None if existing.get('oif_routemap') or existing_oif_prefix_source: command = config_remove_oif(existing, existing_oif_prefix_source) if command: commands.append(command) command = config_default_igmp_interface(existing, delta) if command: commands.append(command) cmds = [] results = {} if commands: commands.insert(0, ['interface {0}'.format(interface)]) cmds = flatten_list(commands) if module.check_mode: module.exit_json(changed=True, commands=cmds) else: load_config(module, cmds) changed = True end_state = get_igmp_interface(module, interface) if 'configure' in cmds: cmds.pop(0) if module.params['restart']: cmd = {'command': 'restart igmp', 'output': 'text'} run_commands(module, cmd) results['proposed'] = proposed results['existing'] = existing_copy results['updates'] = cmds results['changed'] = changed results['warnings'] = warnings results['end_state'] = end_state module.exit_json(**results)