Перейти к содержанию

Nornir

#!/usr/bin/env python3
""" Решение задачи второго дня марафона DevNet

Общий принцип:

1. Собираем со всех устройств структурированные данные
    - switchport interfaces
    - mac address-table
2. Осуществляем поиск нужного MAC адреса по заданным в ТЗ
услвиям - определить порт, к которому физически подлключено
устройство.

Варианты устройств:
1. Клиент на access порту
2. SVI на коммутаторе
3. Маршрутизатор R1, который выступает шлюзом по-умолчанию
для клиентов
"""
import argparse
from nornir import InitNornir
from nornir_scrapli.tasks import (
    send_command
)
from scrapli.response import Response
from tools import find_mac


def main():
    args = get_args()
    macaddress = args.macaddress

    nr = InitNornir(config_file="config.yaml")

    # Выгружаем интерфейсы
    result = nr.run(
        task=send_command,
        command="show interfaces switchport"
    )
    interfaces = process_result(result)

    # Выгружаем MAC таблицы
    result = nr.run(
        task=send_command,
        command="show mac address-table"
    )
    mac_table = process_result(result)

    # Выполняем свое предназначение
    print(find_mac(interfaces, mac_table, macaddress))


def process_result(result):
    """ Возвращает данные в JSON формате
    """
    data = []
    for hostname, multi_result in result.items():
        for result in multi_result:
            responses = getattr(result, "scrapli_response", None)

            # Если результат единичный то превращаем его в список
            if isinstance(responses, Response):
                responses = [responses]

            # Данные получить не удалось
            if not responses:
                exit(f"Get data from {hostname} failed")

            for response in responses:
                # Используем встроенный в scrapli парсер
                data.append({
                    "hostname": hostname,
                    "data": response.textfsm_parse_output()
                })
    return data


def get_args():
    """ Парсер аргументов командной строки
    """
    parser = argparse.ArgumentParser(prog="mac-finder")

    parser.add_argument(
        "macaddress",
        metavar="<MAC>",
        help="MAC адрес искомого устройства"
    )

    return parser.parse_args()


if __name__ == "__main__":
    main()