Моя работа начинается, если мне «прилетел» отчёт об отказе узла связи… +6


Хочу предупредить, чтоб не тратили своё время! Это продолжение размышлений на тему сопровождения L2 сети уровня города. Стоит прочесть эту статью, чтоб понять нужно оно Вам или нет.

Администратор сети:
image
Моя работа начинается если, мне прилетел отчёт об отказе узла связи.

Чтобы понять какие действия от меня требуются, мне необходимо разобраться в том с чем предстоит работать.

Для физической организации сети связи за нас давно придуман стандарт TIA/EIA-606 «Стандарт на администрирование телекоммуникационной инфраструктуры коммерческих зданий(ГОСТ Р 53246-2008, аналог Американского стандарта). Архитектурная инфраструктура сети включает в себя три подсистемы кабельного хозяйства.

  • уровень доступа (access layer);
  • уровень агрегации (distibution layer);
  • уровень ядра (core layer).

Логическая организация того что имеем.

графическое представление того что есть

Теперь рассмотрим, какими данными мы обладаем

  1. Управляющая сеть, через которую можно достучаться по IP к управляемому коммутатору выделенная в отдельный Vlan (vlan 100 на рисунке, untagged на UpLink)
  2. Протокол ARP, который позволит нам спуститься на L2 увидеть мак-адреса,
  3. Таблицы коммутации, покажут какие мак-адреса в каких портах живут.

Причём второй и третий пункты не документированы в силу того что информация обновляется и распределена по всей сети. Другими словами у нас тут проблемка… в случае отказа узла или искажения таблицы коммутации во время флуда усложняется задача поиска точки (порта) отказа. Сам же поиск представляет собой работу с документацией и последовательный (по цепочке) опрос коммутаторов.

Сопровождение документации по портам это трудоёмкая задача в силу того что техническая служба „забывает“ о том что нужно отписаться о проделанной работе по переключению порта помножьте на занесение информации в систему мониторинга то есть тут человеческий фактор проявляет свои негативные эффекты.

Исходя из вышеизложенного нам следует подумать на предмет того как автоматизировать сбор и хранение информации о структуре работающей сети, а так же понять как выполнить быстрое сравнение „сломанной“ ветки и последнего рабочего снимка.

В случае достижения успеха в реализации обоих задач, общее время на поиск причины отказа уменьшится, нагрузка на администратора сети в кризисные моменты снизится.

В качестве средства автоматизации, я планирую использовать Python v3, для работы с MAC и IP адресами библиотеку netaddr (первоначально думал использовать ipaddress, но эта даёт большую свободу действий). В качестве площадки для сбора выступит сервер на котором развёрнут zabbix-proxy основная причина выбора уже работающего сервера — он находится менеджмент-vlan одним из интерфейсов.

Шаг первый выявление „Живых“


Код внутри, ОСТОРОЖНО! Может вызвать раздражение глаз Профи.
import datetime
import json
import re

from netaddr import IPNetwork, IPAddress, EUI
from netaddr.core import AddrFormatError
import subprocess


class AliveHost:
    """
    Средствами операционной системы, а именно ping ip и arp -n ip заполняем поля этого класса
    """

    def __init__(self, address, mac):
        self.ip = IPAddress(address)
        self.mac = EUI(mac)
        self.current_time = datetime.datetime.now()

    def __repr__(self):
        return "{} - {}".format(self.ip, self.mac)

    def __hash__(self):
        # TODO: Какова вероятность совпадения hash-значений сочетания ip+mac???
        return hash((self.ip, self.mac))

    @staticmethod
    def _str_class(o):
        # TODO: Сократить и перенести в метод to_json
        result = {}
        for attr in o.__dict__:
            result.update({attr: str(o.__dict__.get(attr))})
        return result

    def to_json(self):
        return json.dumps(self, default=self._str_class,
                          sort_keys=True, indent=4)


def ping(host):
    """PEP 324 – PEP proposing the subprocess module"""
    h = str(host)
    result = []
    with subprocess.Popen(["ping", "-c 1", h], stdout=subprocess.PIPE) as s_ping:
        if '1 received, 0% packet loss' in str(s_ping.stdout.read()):
            result.append(h)
    if not len(result):
        return None, None
    with subprocess.Popen(["arp", "-n", h], stdout=subprocess.PIPE) as s_ping:
        mac = re.compile(r'(([0-9A-Fa-f]){2}?:){5}([0-9A-Fa-f]){2}')
        result.append(re.search(mac, str(s_ping.stdout.read().decode('utf-8')))[0])
    return result


if __name__ == '__main__':
    alive = []
    for ip in IPNetwork('10.0.0.0/22').iter_hosts():
        try:
            alive.append(AliveHost(*ping(ip)))
        except AddrFormatError:
            continue
        except TypeError:
            continue


Выполняя этот код, мы получим список объектов, которые уже содержат в себе часть нужной для построения дерева информации.

Следующий шаг — Сбор информации с использованием библиотеки telnetlib и формирование примерно таких записей: (alive[0], port_13),(alive[1],alive[2],alive[3]).

Намеренно избегаю пока обсуждение сериализации данных, так как объем собранной информации будет небольшим в частности сеть /24 заняла 24Kб памяти, а следовательно нет никакого смысла спешить.

А вот узнать Ваше мнение на предмет правильности рассуждений или же смысла публикаций хочется уже сейчас.




К сожалению, не доступен сервер mySQL