Child pages
  • Автоматическое раскидывание по сегментам
Skip to end of metadata
Go to start of metadata
  1.  У нас есть некоторое количество сегментов сети созданных по префиксам. Это удобно тем что ManagedObject с адресом из указанной таблицы префиксов автоматически показывается в нужном сегменте.

  2. Однако есть обратная задача - определить к какому сегменту сети относится данный объект, и выставить ему соотвествующий сегмент.
  3. Поскольку руками перелопачивать тысячи объектов нам не хочется - это можно автоматизировать при помощи noc shell

Пример:

from noc.sa.models import *
from noc.inv.models.networksegment import *
for seg in NetworkSegment.objects.filter() :
    if seg.name[:4]=="net-":
        print seg.name
        for obj in  seg.managed_objects :
            print "\t%s / %s (%s -> %s )" % ( obj.name, obj.address,obj.segment,seg.name )
            if obj.segment != seg:
                obj.segment = seg
                obj.save()

В моем примере расставляются только сегменты чье имя начинается с  "net-". Другие сегменты не являются автоматически-генерируемыми и управляются отдельно.

 

 

3 Comments

  1. Unknown User (e_zombie)

    а комментарии к коду что делает каждая строка  чтобы и неофитам было понятно ?

  2. Unknown User (e_zombie)

    Делаем комманду для выполнения операции по раскидывания по сегментам.

    run

    ./noc m-sys

    Пояснения. у меня параметр сегмент закодировано в SNMP параметре sysLocation . этот парамент есть на всех железках с snmp.

    Параметры для получения его из конфигурационного файла находятся в rx_config_ХХХХХ

    Логика работы скрипта такая:

    1. попытаться получить параметр sysLocation из собранного конфигурационного файла.
    2. если это не получилось - обратиться к оборудованию через snmp и взять этот параметр.
    3. проверить что полученное значение соответствует "шаблону"
    4. если полученный шаблон валидный - проверить если ли он в базе. если нет - то создаём.
    5. назначить объекту МО найденный сегмент.

    П.с.

    я знаю что можно это опрос можно сделать средствами питона\нока.

    ./commands/m-sys.py

    # -*- coding: utf-8 -*-

    import re
    import commands

    from noc.core.script.base import BaseScript
    from noc.core.management.base import BaseCommand

    from noc.sa.interfaces.igetversion import IGetVersion
    from noc.sa.models.managedobject import ManagedObject
    from noc.sa.models.managedobject import AdministrativeDomain
    from noc.sa.models.managedobjectprofile import ManagedObjectProfile

    from noc.inv.models.networksegment import NetworkSegment

    '''
    sl - переменная для syslocate общая
    snmpsl - переменная полученная по SNMP


    '''
    class Command(BaseCommand, BaseScript ):
             
        rx_config_huawei = re.compile(r"snmp-agent sys-info location (?P<syslocate>[a-zA-Z0-9.]+)", re.MULTILINE | re.DOTALL)
        rx_config_qtech = re.compile(r"sysLocation (?P<syslocate>[a-zA-Z0-9.]+)", re.MULTILINE | re.DOTALL)
        rx_config_ec = re.compile(r"snmp-server location (?P<syslocate>[a-zA-Z0-9.]+)", re.MULTILINE | re.DOTALL)
        # raisecom,eltex  similar EC
        rx_config_dlink = re.compile(r"config snmp system_location (?P<syslocate>[a-zA-Z0-9.]+)", re.MULTILINE | re.DOTALL)
        
        def handle(self):

             ob = ManagedObjectProfile.objects.get(name='eltex.fttb')
             adm = AdministrativeDomain.objects.get(name='saratov')
             host = 'fsw-5-novastrahanshosse-63-96-sar'
             #mo = ManagedObject.objects.filter(name=host)
             #mo = ManagedObject.objects.filter(object_profile=ob)
             # mo = ManagedObject.objects.filter(administrative_domain=adm,object_profile=ob)
             #mo = ManagedObject.objects.filter(administrative_domain=adm)
             mo = ManagedObject.objects.filter()
             for m in mo:
                 sl = None
                 print m.name, m.address, m.object_profile, m.segment.id

        # пробуем получить сислокейт из конфига. это быстрее чем snmp
                 if m.name !='SAE':
                     try:
                                
    #                      print "start"
    #                     print m.config.read()
                          rx = self.find_re([
                                  self.rx_config_huawei,
                                  self.rx_config_qtech,
                                  self.rx_config_ec,
                                  self.rx_config_dlink,], m.config.read())
                          match = rx.search(m.config.read())
                          # match = rx_config_huawei.search(m.config.read())
    #                      print match
                          sl = match.group("syslocate")
                 
                          print "found syslocate in config: ",sl
    #                      print "-----------------------------------", sl , " ========"
    # dfsfs
                     except:
                         pass
                         print "config grep fail"
                 # проверяем что вернул греп конфигов, если ничего не приехало - лезем в snmp
                     if sl == None:
             
                         if m.snmp_ro != None:
                             cmd = "/usr/bin/snmpget -t 2 -r 1 -v 2c -Oqv -c "+ m.snmp_ro + " "+ m.address + " .1.3.6.1.2.1.1.6.0"
                             snmpsl = commands.getoutput(cmd)
    #                print cmd
                                                
                             if snmpsl != m.segment and not snmpsl[:7]=='Timeout':
                                 print "SNMP segment: " , snmpsl
                                 sl = snmpsl
                             else:
                                 print "SNMP syslocate: None"

                     # надо проверить полученный SYSLOCATE на валидность.
                     if sl != None and (
                             (sl[:2]=="s." and m.administrative_domain.id == AdministrativeDomain.objects.get(name='saratov').id)
                          or (sl[:2]=="b." and m.administrative_domain.id == AdministrativeDomain.objects.get(name='balakovo').id)
                          or (sl[:2]=="e." and m.administrative_domain.id == AdministrativeDomain.objects.get(name='engels').id)
                          or (sl[:2]=="c." and m.administrative_domain.id == AdministrativeDomain.objects.get(name='balashov').id)
                      ):
                         print "valid"

                        # надо проверить есть ли segment с таким именем в БД если нету - то создать
                        #    print NetworkSegment.objects.get(name='ALL').name

                         try:
    #                          print NetworkSegment.objects.get(name=sl).name
                              print "found segment: ", NetworkSegment.objects.get(name=sl).name
                
                        # у МО сегмент не соответствует тому что получено с сети и его надо обновить
                              if m.segment != sl:
                                  print "update MO segment: ", m.name, m.address, sl
                                  m.segment.id = NetworkSegment.objects.get(name=sl).id
                                  m.save()
                              else:
                                  print "segment SNMP=Config=BD"

                         except:
                              print "segment not found in BD - create"
                              segment = NetworkSegment()
                              segment.name = sl
                              segment.save()
                
                              m.segment.id = NetworkSegment.objects.get(name=sl).id
                              m.save()

                     else:
                         print "Segment INVALID"


    if __name__ == "__main__":
        Command().run()
        

  3. Unknown User (e_zombie)

    Посмотрел как отправлять запросы SNMP через активатор. 
     
     from noc.core.service.client import RPCClient, RPCError
     from noc.sa.models.managementobject import ManagementObject
     from noc.lib.mib import mib
     
     mo = ManagedObject.objects.get(name="blablabla")
     RPCClient("activator-%s" % mo.pool.name,calling_service="script1").snmp_v2c_get(mo.address,mo.snmp_ro,"1.3.6.1.2.1.1.2.0")
     
     вернёт, что получили. Если используется профиль аутентицикации - то получить ro можно:
     
     mo.auth_profile.snmp_ro
     
     для резолва OID'ов можно пользоваться мибами:
     mib["SNMPv2-MIB::sysObjectID.0"]
     
     calling_service - будет отображаться в логах активатора.