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 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_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 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 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), 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( 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( 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 = normalize_interface(module.params["interface"]) 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 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 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( 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)
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)
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 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( 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 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", no_log=True), 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 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(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)