예제 #1
0
def find_mac_address_in_device_data(device_data: Dict[str, Any], mac_address: str, physical_ports_only: bool) -> List[Dict[str, Any]]:
    """ Find vlans and ports in switch mac table for spcified mac address """

    findings = netcat.find_regex_ml(netcat.get_command_output(device_data, "show mac address-table"),
            rf"^\*?\s+(\d+)\s+{mac_address}\s+\S+\s+(?:\d+\s+\S+\s+\S+\s+)?(\S+) ?$", hint=mac_address)

    return [
        {
            "mac_address": mac_address,
            "device_name": device_data.get("device_name"),
            "vlan": _,
            "port": __,
            "snapshot_timestamp": device_data.get("snapshot_timestamp"),
        }
        for _, __ in findings if re.search("Gi|Eth", __) or not physical_ports_only
    ]
예제 #2
0
def create_inventory_list(device_name_list: List[str]) -> List[Dict[str, Any]]:
    """ Create inventory list """

    # Time process execution
    start_time = time.monotonic()

    # Setup logger to show process name
    if os.getpid() != netcat.MAIN_PROCESS_PID:
        netcat.bind_logger("SUB_PROC")

    inventory_list = []

    for device_data in get_device_data_list(device_name_list):

        if device_data.get("device_type") == "cisco_switch":
            command_output = netcat.get_command_output(device_data,
                                                       "show version")
            model_numbers = netcat.find_regex_ml(command_output,
                                                 r"^Model number\s+: (\S+)$",
                                                 hint="el n",
                                                 optional=False)
            serial_numbers = netcat.find_regex_ml(
                command_output,
                r"^System serial number\s+: (\S+)$",
                hint="m s",
                optional=False)
            software_versions = netcat.find_regex_ml(
                command_output,
                r"^\*?\s+\d+\s+\d+\s+\S+\s+(\S+) .*$",
                hint="  W",
                optional=False)

        elif device_data.get("device_type") == "cisco_router":
            command_output = netcat.get_command_output(device_data,
                                                       "show version")
            model_numbers = netcat.find_regex_ml(
                command_output,
                r"^[Cc]isco (\S+) .+ bytes of memory.$",
                hint="s of m",
                optional=False)
            serial_numbers = netcat.find_regex_ml(
                command_output,
                r"^Processor board ID (\S+)$",
                hint="d I",
                optional=False)
            software_versions = netcat.find_regex_ml(
                command_output,
                r"^Cisco IOS Software,? .+ Version ([^\s,]+), .+$",
                hint="o I",
                optional=False)

        elif device_data.get("device_type") == "cisco_nexus":
            command_output = netcat.get_command_output(device_data,
                                                       "show version")
            model_numbers = netcat.find_regex_ml(
                command_output,
                r"^\s+cisco Nexus[^ ]* (\S+) .+$",
                hint="has",
                optional=False)
            serial_numbers = netcat.find_regex_ml(
                command_output,
                r"^\s+Processor Board ID (\S+)$",
                hint=" Pr",
                optional=False)
            software_versions = netcat.find_regex_ml(
                command_output,
                r"^\s+(?:system|NXOS):\s+version (\S+)$",
                hint="ver",
                optional=False)

        elif device_data.get("device_type") == "cisco_asa":
            command_output = netcat.get_command_output(device_data,
                                                       "show version")
            model_numbers = netcat.find_regex_ml(command_output,
                                                 r"^Hardware:\s+([^ ^,]+),.+$",
                                                 hint="Har",
                                                 optional=False)
            serial_numbers = netcat.find_regex_ml(command_output,
                                                  r"^Serial Number: (\S+)$",
                                                  hint="Ser",
                                                  optional=False)
            software_versions = netcat.find_regex_ml(
                command_output,
                r"^Cisco .+ Software Version (\S+) .*$",
                hint="e S",
                optional=False)

        elif device_data.get("device_type") == "cisco_asa_mc":
            command_output = netcat.get_command_output(device_data,
                                                       "show version")
            model_numbers = netcat.find_regex_ml(command_output,
                                                 r"^Hardware:\s+([^ ^,]+),.+$",
                                                 hint="Har",
                                                 optional=False)
            serial_numbers = netcat.find_regex_ml(command_output,
                                                  r"^Serial Number: (\S+)$",
                                                  hint="Ser",
                                                  optional=False)
            software_versions = netcat.find_regex_ml(
                command_output,
                r"^Cisco .+ Software Version (\S+) .*$",
                hint="e S",
                optional=False)

        elif device_data.get("device_type") == "paloalto":
            command_output = netcat.get_command_output(device_data,
                                                       "show system info")
            model_numbers = netcat.find_regex_ml(command_output,
                                                 r"^model: (\S+)$",
                                                 hint="el:",
                                                 optional=False)
            serial_numbers = netcat.find_regex_ml(command_output,
                                                  r"^serial: (\S+)$",
                                                  hint="ser",
                                                  optional=False)
            software_versions = netcat.find_regex_ml(command_output,
                                                     r"^sw-version: (\S+)$",
                                                     hint="sw-",
                                                     optional=False)

        elif device_data.get("device_type") == "f5":
            command_output = netcat.get_command_output(device_data,
                                                       "show sys hardware")
            model_numbers = netcat.find_regex_ml(command_output,
                                                 r"^  Name\s+(BIG-IP \S+).*$",
                                                 hint="BIG",
                                                 optional=False)
            serial_numbers = netcat.find_regex_ml(
                command_output,
                r"^\s+Host Board Serial\s+(\S+)$",
                hint=" Ho",
                optional=False)

            # Fix for vf2lb[12]mgmt that dont show serial numbers, can be removed after VF2 decom
            if serial_numbers == []:
                serial_numbers = ["UNKNOWN"]

            command_output = netcat.get_command_output(device_data,
                                                       "show sys version")
            software_versions = netcat.find_regex_ml(command_output,
                                                     r"^\s+Version\s+(\S+)$",
                                                     hint="  V",
                                                     optional=False)

        else:
            inventory_list.append(
                {"device_name": device_data.get("device_name")})
            continue

        from uuid import uuid1
        inventory_list.append({
            "uuid":
            uuid1(),
            "snapshot_timestamp":
            device_data.get("snapshot_timestamp"),
            "device_name":
            device_data.get("device_name"),
            "device_type":
            device_data.get("device_type"),
            "chasis": [{
                "model": _,
                "serial": __,
                "software": ___
            } for _, __, ___ in zip(model_numbers, serial_numbers,
                                    software_versions)],
        })

    # Time process execution
    end_time = time.monotonic()

    netcat.LOGGER.debug(
        f"Inventory data created for {len(device_name_list)} devices in {end_time - start_time:.2f}s"
    )

    return inventory_list
예제 #3
0
def find_ip_address_in_device_data(device_data: Dict[str,
                                                     Any], ip_address: str,
                                   use_arp: bool, use_dhcp: bool,
                                   use_dsnp: bool) -> List[Dict[str, Any]]:
    """ Find data line containing ip address in device data structure """

    results: List[Tuple[Any, str, str]] = []

    if device_data.get("device_type") == "cisco_switch":
        if use_dsnp:
            results += [
                (_, "DSNP", f"[ l2_int: {___} ], [ vlan: {__} ]")
                for _, __, ___ in netcat.find_regex_ml(
                    netcat.get_command_output(device_data,
                                              "show ip dhcp snooping binding"),
                    rf"^(\S+)\s+{ip_address}\s+\d+\s+\S+\s+(\d+)\s+(\S+)\s*$",
                    hint=ip_address)
            ]

    elif device_data.get("device_type") == "cisco_router":

        if use_arp:
            results += [(
                _, "ARP", f"[ l3_int: {__} ]"
            ) for _, __ in netcat.find_regex_ml(
                netcat.get_command_output(device_data, "show ip arp"),
                rf"^Internet\s+{ip_address}\s+\S+\s+(\S+)\s+ARPA\s+(\S+)\s*$",
                hint=ip_address)]

        if use_dhcp:
            results += [(_, "DHCP", f"") for _ in netcat.find_regex_ml(
                netcat.get_command_output(device_data, "show ip dhcp binding"),
                rf"^{ip_address}\s+(\S+)\s.+$",
                hint=ip_address)]

    elif device_data.get("device_type") == "paloalto":

        if use_arp:
            results += [
                (__, "ARP", f"[ l3_int: {_} ]")
                for _, __ in netcat.find_regex_ml(
                    netcat.get_command_output(device_data, "show arp all"),
                    rf"^(\S+)\s+{ip_address}\s+(\S+)\s+\S+\s.*$",
                    hint=ip_address)
            ]

        if use_dhcp:
            results += [
                (_, "DHCP", f"[ name: {__} ]")
                for _, __ in netcat.find_regex_ml(
                    netcat.get_command_output(
                        device_data, "show dhcp server lease interface all"),
                    rf"^{ip_address}\s+(\S+)\s+(\S+) .*$",
                    hint=ip_address)
            ]

    else:
        netcat.LOGGER.warning(
            f"{netcat.fn()}: Unknown device data type value '{device_data.get('device_type')}'"
        )
        return []

    return [{
        "snapshot_timestamp": device_data.get("snapshot_timestamp"),
        "mac_address": netcat.standardize_mac_address(_),
        "device_name": device_data.get("device_name"),
        "source": __,
        "other_info": ___,
    } for _, __, ___ in results]
예제 #4
0
                break

            netcat.LOGGER.warning(
                f"Installation of version {requested_software_version} failed, will retry up to three times..."
            )
            print("***", command_output, "***")

        else:
            raise netcat.CustomException(
                f"Failed three attempts to install version {requested_software_version}"
            )

        # Wait till both of the firewalls have ha working properly and then reboot
        for _ in range(30):
            command_output = self.send_command("show high-availability all")
            ha_states = netcat.find_regex_ml(command_output,
                                             r"^\s+State:\s+(\S+).*$")
            if len(ha_states) < 2:
                raise netcat.CustomException(
                    f"Cannot properly read firewalls HA state '{ha_states}'")

            if ha_states[0] in {"active", "passive"
                                } and ha_states[1] in {"active", "passive"}:
                netcat.LOGGER.info(
                    f"Firewalls HA states look okay: {ha_states}")
                break

            netcat.LOGGER.info(
                f"Firewalls HA states do not look okay yet: {ha_states}, waiting one more minute..."
            )
            time.sleep(60)
예제 #5
0
def find_broken_links_per_device(
        device_data: Dict[str, Any]) -> List[Dict[str, Any]]:
    """ Search for any link that is down (but not admin down) on Cisco routers and Palo Alto firewalls """

    # Time process execution
    start_time = time.monotonic()

    # Setup logger to show process name
    if os.getpid() != netcat.MAIN_PROCESS_PID:
        netcat.bind_logger("SUB_PROC")

    broken_links = []

    if device_data.get("device_type") == "cisco_router":

        # Look for any broken link
        for interface_name, interface_ip_address in netcat.find_regex_ml(
                netcat.get_command_output(device_data,
                                          "show ip interface brief"),
                rf"^([^\s]*(?:Ethernet|Tunnel)\S+)\s+(\S+)\s+\S+\s+\S+\s+(?:up|down)\s+down\s*$"
        ):

            broken_link = {
                "uuid": uuid.uuid1(),
                "device_name": device_data.get("device_name"),
                "device_type": device_data.get("device_type"),
                "interface_name": interface_name,
                "interface_name_encoded": interface_name.replace("/", "_"),
                "interface_ip_address": interface_ip_address,
            }

            # Search for latest device_info structure that has broken link in UP state and record its timestamp
            device_data_list = db.get_device_data_list__c(
                device_data.get("device_name", ""),
                command_list=["show ip interface brief"])

            for device_data in device_data_list:
                regex_interface_name = interface_name.replace("/",
                                                              "\\/").replace(
                                                                  ".", "\.")
                if netcat.find_regex_sl(
                        netcat.get_command_output(device_data,
                                                  "show ip interface brief"),
                        rf"(^[^\s]*{regex_interface_name}\s+\S+\s+\S+\s+\S+\s+up\s+up\s*$)",
                        hint=interface_name,
                        optional=False):
                    broken_link["snapshot_timestamp"] = device_data.get(
                        "snapshot_timestamp")
                    break

            broken_links.append(broken_link)

    elif device_data.get("device_type") == "paloalto":

        # Skip device if its not in active ha state
        if netcat.find_regex_sl(
                netcat.get_command_output(device_data,
                                          "show high-availability all"),
                r"\s+State: (\S+) .*$") not in {
                    "active", "active-primary", "active-secondary", ""
                }:
            return []

        # Look for any broken link
        for interface_name, interface_mac_address in netcat.find_regex_ml(
                netcat.get_command_output(device_data, "show interface all"),
                r"^((?:ethernet|ae)\S+)\s+\d+\s+ukn\/ukn\/down\S+\s+(\S+)\s*$"
        ):

            broken_link = {
                "uuid": uuid.uuid1(),
                "device_name": device_data.get("device_name"),
                "device_type": device_data.get("device_type"),
                "interface_name": interface_name,
                "interface_name_encoded": interface_name.replace("/", "_"),
                "interface_ip_address": "N/A",
                "interface_mac_address": interface_mac_address,
            }

            # Search for latest device_info structure that has broken BGP session in UP state and record its timestamp
            device_data_list = db.get_device_data_list__c(
                device_data.get("device_name", ""),
                command_list=["show interface all"])

            for device_data in device_data_list:
                regex_interface_name = interface_name.replace("/",
                                                              "\\/").replace(
                                                                  ".", "\.")
                if netcat.find_regex_ml(
                        netcat.get_command_output(device_data,
                                                  "show interface all"),
                        rf"(^{regex_interface_name}\s+\S+\s+\S+\/up\s+\S+\s*$)",
                        hint=interface_name,
                        optional=False):
                    broken_link["snapshot_timestamp"] = device_data.get(
                        "snapshot_timestamp")
                    break

            broken_links.append(broken_link)

    else:
        netcat.LOGGER.warning(
            f"{netcat.fn()}: Unknown device data type value '{device_data.get('type')}'"
        )

    # Time process execution
    end_time = time.monotonic()

    netcat.LOGGER.debug(
        f"Created broken links list of {len(broken_links)} links in {end_time - start_time:.2f}s"
    )

    return broken_links
예제 #6
0
def find_broken_bgp_sessions_per_device(
        device_data: Dict[str, Any]) -> List[Dict[str, Any]]:
    """ Search for broken BGP sessions on Cisco routers and Palo Alto firewalls """

    # Time process execution
    start_time = time.monotonic()

    # Setup logger to show process name
    if os.getpid() != netcat.MAIN_PROCESS_PID:
        netcat.bind_logger("SUB_PROC")

    broken_bgp_sessions = []

    if device_data.get("device_type") == "cisco_router":

        # Look for any broken BGP sessions
        for bgp_session_peer_ip, bgp_session_peer_asn in netcat.find_regex_ml(
                netcat.get_command_output(device_data, "show ip bgp summary"),
                r"^(\S+)\s+\d\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\S+\s+(?:Idle|Active)$"
        ):

            broken_bgp_session = {
                "uuid": uuid.uuid1(),
                "device_name": device_data.get("device_name"),
                "device_type": device_data.get("device_type"),
                "peer_ip": bgp_session_peer_ip,
                "peer_asn": bgp_session_peer_asn,
            }

            # Search for latest device_data document that has broken BGP session in UP state and record its timestamp
            device_data_list = db.get_device_data_list__c(
                device_data.get("device_name", ""),
                command_list=["show ip bgp summary"])

            for device_data in device_data_list:
                if netcat.find_regex_ml(
                        netcat.get_command_output(device_data,
                                                  "show ip bgp summary"),
                        rf"(^{bgp_session_peer_ip}\s+\d\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\S+\s+\d+$)",
                        hint=bgp_session_peer_ip,
                        optional=False):
                    broken_bgp_session["snapshot_timestamp"] = device_data.get(
                        "snapshot_timestamp")
                    break

            broken_bgp_sessions.append(broken_bgp_session)

    elif device_data.get("device_type") == "paloalto":

        # Skip device if its not in active ha state
        if netcat.find_regex_sl(
                netcat.get_command_output(device_data,
                                          "show high-availability all"),
                r"\s+State: (\S+) .*$") not in {
                    "active", "active-primary", "active-secondary", ""
                }:
            return []

        # Look for any broken BGP sessions
        for bgp_session_peer_asn, bgp_session_peer_ip in netcat.find_regex_ml(
                netcat.get_command_output(device_data,
                                          "show routing protocol bgp summary"),
                r"^\s+peer \S+\s+ AS (\d+), (?:Connect|Active), IP (\S+)$"):

            broken_bgp_session = {
                "uuid": uuid.uuid1(),
                "device_name": device_data.get("device_name"),
                "device_type": device_data.get("device_type"),
                "peer_ip": bgp_session_peer_ip,
                "peer_asn": bgp_session_peer_asn,
            }

            # Search for latest device_data structure that has broken BGP session in UP state and record its timestamp
            device_data_list = db.get_device_data_list__c(
                device_data.get("device_name", ""),
                command_list=[
                    "show routing protocol bgp summary",
                    "show high-availability all"
                ])

            for device_data in device_data_list:
                if netcat.find_regex_sl(
                        netcat.get_command_output(
                            device_data, "show routing protocol bgp summary"),
                        rf"(^\s+peer \S+\s+ AS \d+, Established, IP {bgp_session_peer_ip})$",
                        hint=bgp_session_peer_ip,
                        optional=False):
                    broken_bgp_session["snapshot_timestamp"] = device_data.get(
                        "snapshot_timestamp")
                    break

            broken_bgp_sessions.append(broken_bgp_session)

    else:
        netcat.LOGGER.warning(
            f"{netcat.fn()}: Unknown device data type value '{device_data.get('type')}'"
        )

    # Time process execution
    end_time = time.monotonic()

    netcat.LOGGER.debug(
        f"Created broken bgp session list of {len(broken_bgp_sessions)} sessions in {end_time - start_time:.2f}s"
    )

    return broken_bgp_sessions