Child pages
  • Pyrule для FM который пригодится каждому.
Skip to end of metadata
Go to start of metadata

    Есть такая ситуация, в нашей сети используются L3 свичи, маршрутизация на них устроена таким образом что в одном влане на каждом свиче настроен ip интерфейс и включен протокол маршрутизации, в данном случае EIGRP. Беда в том что когда пропадает связь с одним из свичей то в зависимости от размера сегмента, может возникнуть от 5 до 30 алармов, если например из-за проблем с питанием на узле, несколько свичей падают, то в FM возникает до сотни бессмысленных алармов. Решение простое, непонятно почему до сих пор не реализовано в апстриме.

from noc.fm.models import *
from noc.inv.models import *

@pyrule

def set_root_for_eigrp(alarm):

    eigrp = AlarmClass.objects.get(name="Network | EIGRP | Neighbor Down")
    alarms = ActiveAlarm.objects.filter(alarm_class=eigrp.id)
    ipif = SubInterface.objects.filter(managed_object=alarm.managed_object.id, enabled_afi=["IPv4"])

    for a in alarms:
        for i in ipif:
            if a.vars['neighbor']==i.ipv4_addresses[0].split("/")[0]:
                a.set_root(alarm)

Поясню логику на всякий случай. Этому пирулю задается интерфейс IAlarmTrigger, а в Alarm Trigger прописываем этот пируль для алармов Alarm Class RE: "NOC \| Managed Object \| Ping Failed". Что происходит:

1) Падает свич. через 15 секунд соседи обнаруживают не доступность и присылают сообщения в нок

2) В течение минуты нок тоже понимает, что свич недоступен, поднимает аларм "Ping failed"

3) По этому аларму срабатывает триггер и выполняется пируль

4) В пируль передается этот аларм ping failed. из него узнаем какая железка стала недоступной и для этой железки получаем список всех ее интерфейсов с ipv4 адресами, этот список кладется в ipif

5) Два цикла, перебираем все алармы EIGRP Neighbor Down и смотрим не относятся ли они к одному из интерфейсов нашей железки, если так то указываем наш изначальный аларм как причину (root cause) для каждого падения eigrp

 

4 Comments

  1. Unknown User (dv)

    Можно оптимизировать примерно так

    def set_root_for_eigrp(alarm):
     
        eigrp = AlarmClass.objects.get(name="Network | EIGRP | Neighbor Down")
        ips = set(
            a.split("/", 1)[0] for a in [
                i.ipv4_addresses
                for i in SubInterface.objects.filter(
                    managed_object=alarm.managed_object.id, enabled_afi="IPv4")
            ])
     
        alarms = ActiveAlarm.objects.filter(alarm_class=eigrp.id, vars__neighbor__in=ips)
    
        for a in alarms:
            a.set_root(alarm)
    1. Unknown User (zi)

      да, наверное так лучше, проверю завтра у себя, мой вариант мне показалось работает не совсем быстро, уходит 2-3 секунды (на тестовом свиче с парой интерфейсов, чуть меньше секунды)

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

      но зато мой вариант проще, я так и не смог понять как твой вариант работает, хотя логика вроде видна

      UDP. i.ipv4_addresses[0] надо делать, мне подходит этот вариант, у меня нет secondary адресов на портах с включенным роутингом. или правильней - разворачивать этот список в цикле


      этот вариант ксати заметно быстрее

  2. Unknown User (zi)

    Окончательный вариант который у меня работает

    from noc.fm.models import *
    from noc.inv.models import *
    @pyrule
    def set_root_for_eigrp(alarm):
     
        eigrp = AlarmClass.objects.get(name="Network | EIGRP | Neighbor Down")
        ips = set(
            a.split("/", 1)[0] for a in [
                i.ipv4_addresses[0]
                for i in SubInterface.objects.filter(
                    managed_object=alarm.managed_object.id, enabled_afi="IPv4")
            ])
     
        alarms = ActiveAlarm.objects.filter(alarm_class=eigrp.id, vars__neighbor__in=ips)
     
        for a in alarms:
            a.set_root(alarm)
        if len(alarms)>0:
            alarm.change_severity("noc", 1000)

    в конце добавил повышение severity чтобы отделять реальные алармы и просто свичи которые еще не были установлены на сети

  3. Unknown User (zi)

    замечен такой баг

    когда железка флапает, то алармы не всегда схлопываются, это видимо случается когда Ping Failed пришел, а сообщения о падении EIGRP еще не пришли, или может не классифицировались

    вообще такие ситуации странны, hold time у нас по-умолчанию 15 сек, и нок пускает 3 пинга с таймаутом 5сек, нужно чтобы очень особым образом распределились промежутки, чтобы это происходило, но что характерно, оно происходит.

     

    будем ждать штатный механизм без подобных проблем