Wie wir die Netzwerküberwachung für 14.000 Objekte durchgeführt haben

    Wir hatten 14.000 Objekte, zabbix, api, python und eine Zurückhaltung, Objekte von Hand hinzuzufügen. Unter dem Aspekt, wie Netzwerkmanager die Überwachung mit dem automatischen Hinzufügen von Netzwerkknoten implementiert haben, und ein wenig darüber, welchen Schmerz ich durchmachen musste.

    Dieser Artikel konzentriert sich mehr auf Netzwerktechniker mit wenig Erfahrung in Python. Um die Überwachung zu automatisieren und die Lebens- und Arbeitsqualität zu verbessern, muss die gesamte Objektflotte nicht manuell aktualisiert werden.



    Kurz gesagt, wir haben eine Überwachung aufgebaut


    Hallo! Mein Name ist Alexander Prokhorov und zusammen mit dem Team von Netzwerkingenieuren in unserer Abteilung arbeiten wir an einem Netzwerk in # ITX5. Unsere Abteilung entwickelt Netzwerkinfrastruktur, Überwachung und Netzwerkautomatisierung. Ja, und alles rund um die Datenübertragung.



    Ich würde das Überwachungssystem in 5 Unteraufgaben aufteilen:

    • Stammdaten herunterladen
    • Abrufen von Informationen zum Status von Objekten
    • Auslöser und Warnungen
    • Berichterstattung
    • Visualisierung

    In diesem Artikel möchten wir Ihnen mitteilen, wie wir die Integration der Überwachung mit Stammdaten in unser Unternehmen vorgenommen haben.

    Wir haben 14.000 Einzelhandelsimmobilien und die erste Aufgabe, die wir gelöst haben, war die Ermittlung unzugänglicher Objekte, deren Anzahl und geografische Verteilung.

    Die Überwachung wurde auf Zabbix durchgeführt . Kurz gesagt, warum - Glück und Vermächtnis. Der Rest:

    Lange Geschichte.
    Angefangen hat alles mit der Installation der Überwachung auf einem Computer unter dem Tisch ...

    Als ich 2013 zur Arbeit in der Firma kam, hatten wir keine Netzwerküberwachung, obwohl das Netzwerk zu dieser Zeit groß war, ungefähr 4000 Objekte. Wir haben am häufigsten von massiven (und nicht so massiven) Stürzen durch den Lawinen-ähnlichen Eingang von Bewerbungen, Benutzern oder aus anderen Abteilungen erfahren.



    Die erste Version wurde mit Zabbix 1.8 installiert. Zabbix 1.8 ist ein Produkt, das immer mehr an Fahrt gewinnt (modisch, modern, für Jugendliche), leichtgewichtig und erschwinglich ist und Open Source für eine große Community installiert. Wir hatten einfach Glück mit der Wahl.

    Es gab keine Ressourcen für die Installation, niemand hat darum gebeten. Es war unklar, ob dies überhaupt funktionieren würde, niemand hatte Implementierungserfahrung. Aber wir brauchten, und wir installierten es auf dem Computer "unter dem Tisch". Redundanzstufe - UPS.

    Die Hauptfrage nach der Installation ist, wie alle Objekte (4k!) In die Überwachung gegossen werden und gleichzeitig Anwendungen erstellt werden, die bereits in Remedy hängen. Zabbix unterstützte bereits den Import / Export von XML mit Daten auf Hosts. Die Anzahl der Objekte ist groß. Es machte keinen Sinn, eine separate Gruppe für das Objekt zu erstellen (und sie wurde nicht angezeigt). Daher wurde beschlossen, den Objektrouter als Netzwerkknoten hochzuladen. Ein Großteil der Netzwerkgeräte wurde nicht gesteuert (bereits verwaltet).

    Das Parsen unserer Datei mit Netzwerk-Hosts (IPAM in Excel) wurde durchgeführt und in XML umformatiert, das Zabbix zu verdauen bereit ist. Nicht das erste Mal, aber alle Hosts wurden geladen, alle drei Monate wurde eine Aktualisierung durchgeführt, die geschlossenen Objekte wurden entfernt und neue hinzugefügt. Im Laufe der Zeit stellte sich heraus, dass Zabbix die wichtigste und einzige Informationsquelle für uns und die Hotline für die Verfügbarkeit von Einrichtungen und vor allem für Massenstürze war. Dadurch konnte die Hotline auch nachts über Massenunfälle erfahren und Ingenieure mit Anrufen wecken (übrigens war es einfacher zu leben, wenn niemand davon wusste). Nicht immer führten nächtliche Stromausfälle im Büro dazu, dass die USV die Überwachung unseres Netzwerks angemessen aufrechterhielt. Irgendwann wurden wir schonBackups machen. Weil Da die Überwachung instabil und zeitweise war, beschlossen die Unternehmen, eine Gruppe zu gründen, die sich ausschließlich dieser Aufgabe widmet. Sehr bald begann sie, ein zentrales Zabbix zu implementieren, das nicht nur das Netzwerk überprüft.

    Unser alter Zabbix lebte weiterhin unter dem Tisch. Nach dem Hinzufügen einer bestimmten Anzahl von Elementen verlangsamte sich die Datenbank etwas, das Web, die Warteschlange und die Abrufverzögerung nahmen zu, so dass ich bald zwei weitere Computer als Proxy besorgen musste und sie alle in das Kreuz steckte, sodass die reale Reservierung (und der Platz unter dem Tisch) vorbei war. . Das Leben darin wurde aufrechterhalten, um der Überwachung und Beobachtung schnell eine Art benutzerdefinierten Parameter hinzuzufügen. Für den Rest sind wir zu einem zentralisierten umgezogen.

    Alle IT-Geräte - Router, Server, Registrierkassen, Terminals - wurden zentral überwacht. Nach einer Weile wurde er von einer Vielzahl von Gegenständen überwältigt. Um auf unschätzbare Informationen zur Barrierefreiheit zuzugreifen, musste man ein bisschen warten, vielleicht sogar einen Kaffee trinken. Darüber hinaus stellten wir immer mehr Anforderungen an eine spezifischere und individuellere Netzwerküberwachung. Nachdem wir zu dieser Zeit einige Erfahrungen mit dem System gesammelt hatten, haben wir uns entschlossen, die alte Implementierung von Grund auf neu zu machen, aber zu Recht - unter dem Namen zabbix.noc.x5.ru. Sie befand sich im Rechenzentrum mit der Implementierung der erforderlichen Funktionen durch uns. Über diese Einführung und den Hauptteil des Artikels.

    Die Zabbix-Version ist 3.0 LTS . Nur innerhalb der LTS-Versionen aktualisiert.

    Konfiguration - 4 virtuelle Maschinen: Server + Datenbank, Proxy, Proxy, Web

    Nach Ressourcen haben wir versucht, die Empfehlungen auf zabbix.com für eine große und sehr große Implementierung zu befolgen .

    Das erste Problem, mit dem wir konfrontiert waren, war das automatische Hinzufügen von Netzwerkknoten zur Überwachung. Regular Discovery verschwand sofort. Unser Netzwerkangebot erstreckt sich über alle Freiflächen des Supernets 10/8. Viele Adressen müssten abgefragt werden, und die automatische Erkennung würde viele Systemressourcen in Anspruch nehmen, aber das Problem des Hinzufügens nicht technischer Informationen zu einem Objekt nicht lösen.

    So fügen Sie Objekte hinzu


    Die Lösung bestand darin, externe Skripte zum Hinzufügen von Objekten zu verwenden. Stammdaten zu Verkaufsobjekten wurden in der im Unternehmen verwendeten SAP gefunden. Der synchronisierte Zugriff auf den Web-Service zum Hochladen von Daten direkt aus SAP ist nicht zustande gekommen, die Anforderung für alle Objekte hat eine Weile gedauert. Einen asynchronen Anruf getätigt. Genau um Mitternacht eine vollständige Entladung von SAP entwickelt sich auf dem FTP in Form von XML , und im Laufe des Tages fallen sie in die XML ‚ki mit diff'ami der neuesten Versionen.

    Zabbix hat die Zabbix-API zum Laden von Daten verwendet und über Python damit interagiert .

    In der ersten Phase wurde der Datensatz ermittelt, den wir zum Erstellen des Objekts benötigen. Wir verwenden alle erhaltenen Merkmale zur korrekten Klassifizierung eines Objekts im System oder zur weiteren Vereinfachung. Diese Zeichen umfassen:

    • IP-Adresse - das wichtigste Feld zum Erstellen einer Überwachungsschnittstelle
    • SAP ID - Wir haben eine eindeutige Objektkennung
    • Status - offen / geschlossen
    • Name - Der Name oder die Nummer des Objekts, die häufig von Benutzern bei der Kontaktaufnahme verwendet wird
    • Standort - physikalische Adresse
    • Telefon - Kontakttelefon
    • Gruppen - Diese Gruppe von Gruppen wird basierend auf dem Typ und dem Ort des Objekts gebildet



    Sap-sync.py-Modul


    XML von SAP
    12344321-Пятерочка192.168.1.5031308580с.МониторинговоеМосквоская обл.Ленина ул.1(999)777-77-77CHCH_MSKРегион ЦентральныйCH_MSK_DОбъект открыт


    sap-sync.py
    #!/usr/bin/python3
    import sys, os, getopt, ipaddress
    from datetime import datetime as dt
    from zabbix.api import ZabbixAPI
    import xml.etree.cElementTree as et
    from report import report
    import existhost
    def ping(ip):
        if os.system('ping -c 2 -W 1 %s > /dev/null'%ip) == 0:
            return True
        else:
            return False
    def main(argv):
        global opath
        try:
            opts, args = getopt.getopt(argv,"hp:",["path="])
        except getopt.GetoptError:
            print('sync-sap-chg.py -p ')
            sys.exit(2)
        for opt, arg in opts:
            if opt == '-h':
                print('sync-sap-chg.py -p ')
                sys.exit()
            elif opt in ("-p", "--path"):
                opath = arg
    def asynchronization(file, reportdata):
     zapi = ZabbixAPI(url='http://z.noc.x5.ru', user='user', password='pwd')
     #Константы, которые потом пригодятся
     left_kidney = '17855'
     right_kidney = '17856'
     f_type={'S':'Super','D':'DK','H':'Giper','A':'DK'}
     format={'D':'13','S':'14','H':'12','A':'13'}
     region={'CT':'21','UR':'19','SZ':'17',~omit~}
     try:
      #Начинаем разбор XML
      tree = et.ElementTree(file=file)
      root = tree.getroot()
      for werks in root.iter('werks'):
    	#Создаем структуру словаря для объекта Zabbix
    	interfaces=[{
    	 'main':'1',
    	 'type':'2',
    	 'useip':'1',
    	 'port':'161'
    	}]
    	shop={
    	 'inventory':{},
    	 'interfaces':interfaces,
    	 'groups':[],
    	 'templates':[{'templateid':'10194'}],
    	 'inventory_mode':'1'
    	}
    	#Данные, которые будем искать в XML
    	di = {
    	 'WERKS':'',
    	     ~omit~,
    	 'STATUS':'Object Opened'
    	}
    	#Переводим все в словарь
    	for item in werks:
    	  di[item.tag] = item.text
    	  #Достаем из SAPID только цифры
    	  if item.tag == 'WERKS':
    	    n_proxy = ''.join(filter(lambda x: x.isdigit(), item.text))
    	  #Находим IP роутера по адресу сервера. Подсеть везде /26
    	  try:
    		ipaddress.ip_interface('%s/%s'%(di['PLANT_IP'].strip(),26))
    		ip_chk = True
    	  except:
    		ip_chk = False
    		#Дальнейшая обработка, только если IP адрес верный
    		if (di['PLANT_IP'] != '1.1.1.1') and ip_chk:
    		   #Записываем данные в словарь
    		   if di['FORMAT'][-1] in ['D','A','S','H']:
    			  shop['inventory']['alias']=di['WERKS']
    			  shop['inventory']['name']=di['NAME1']
    			  shop['inventory']['poc_1_phone_a']=di['TEL_NUMBER']
    			  shop['inventory']['location']=di['STREET']
    		   #Особенности для каждого формата
    		   if (di['FORMAT'][-1] in ['H']):
    			  shop['host']=f_type[di['FORMAT'][-1]]+di['WERKS']
    			  shop['interfaces'][0]['ip']=str(ipaddress.ip_interface('%s/%s'%(di['PLANT_IP'].strip(),24)).network[1])
    			  #Добавляем ID шаблона мониторинга для объекта
    			  shop['templates'][0]['templateid']='29529'
    		   elif (di['FORMAT'][-1] in ['S']):
    			  ~omit~
    		   #For D balance in proxies
    		   if int(n_proxy[-1]) % 2 == 0:
    			  shop['proxy_hostid'] = right_kidney
    		   else:
    			  shop['proxy_hostid'] = left_kidney
    		   #В inventory тоже добавим IP
    		   shop['inventory']['oob_ip']=shop['interfaces'][0]['ip']
    		   #Назначение групп по словарям format и region
    		   shop['groups']=[{'groupid':'9'}]
    		   shop['groups'].append({'groupid':format[di['FORMAT'][-1]]})
    		   shop['groups'].append({'groupid':region[di['FORMAT'][:2]]})
    		   #Проверка статуса магазина
    		   if di['STATUS'] == 'Объект открыт':
    			  shop['status']='0'
    		   else:
    			  shop['status']='1'
    		   #Записать текущую дату
    		   T = dt.date(dt.now()).strftime("%d %B %Y")
    		   shop['inventory']['date_hw_decomm'] = T
    		   #Проверить есть ли такой хост в Zabbix
    		   hostid = existhost.exist(shop['host'])
    		   ip = shop['interfaces'][0]['ip']
    		   #Если новый - создаем!
    		   if hostid == 0 and shop['status'] == '0' and ping(ip):
    			  zapi.host.create(shop)
    			  reportdata['new'].append(di['WERKS'])
    		   #Если уже есть - обновляем!
    		   elif hostid != 0 and di['PLANT_IP'] != '1.1.1.1':
    			  #Указываем какой HOSTID обновляем
    			  shop['hostid']=hostid
    			  #При обновлении нужно отрезать интерфейсы
    			  shop.pop('interfaces')
    			  zapi.host.update(shop)
    			  reportdata['update'].append(di['WERKS'])
      #Переместить обработанный файл в архив
      os.system('mv %s /mnt/ftp/old_data/'%(file))
     except:
      reportdata['error'].append(di['WERKS'])
      report('Ошибка с файлом %s. Объект с ошибкой:%s'%(file, str(reportdata['error'])), 'SAP Sync Failed!')
      sys.exit()
    def checking(path):
    	files = os.listdir(path)
    	files.sort()
    	reportdata ={'new':[], 'update':[], 'error':[]}
    	for file in files:
    		asynchronization(path+file, reportdata)
    	if files != []:
    		report('Файлы %s успешно синхронизированы! \n Добавлено %s объектов. \n Их sap:\n %s. \n Обновлено %s объектов. \n Их sap:\n %s'%(str(files), len(reportdata['new']), str(reportdata['new']), len(reportdata['update']), str(reportdata['update'])), 'SAP Sync Succeed!')
    if __name__ == "__main__":
    	main(sys.argv[1:])
    	checking(opath)
    


    Der Hauptzweck dieses Moduls besteht darin , XML zu analysieren und in JSON für die Zabbix-API zu übersetzen. In diesem Fall ist es sehr praktisch, Python-Wörterbücher wie Sie müssen sie nicht zusätzlich formatieren - mit dem Modul zabbix.api können Sie ihm einfach ein Wörterbuch mit der richtigen Struktur zuführen. JSON mit einer Struktur sieht folgendermaßen aus:

    {
          'host': 'Hostname'
          'groups': [...]
          'interfaces': [{},{},{}]
          'inventory': {}
          'templates': [{},{},{}]
          'inventory_mode': '1'
          'proxy_hostid': 'INT'
          'status': '0'
    }
    [] - массив
    {} - словарь
    

    In unserem Feld mit der IP-Adresse in SAP wird die Serveradresse gespeichert, nicht der Router, aber mit dem Modul ipaddress betrachten wir die erste Subnetzadresse, die in unserem Fall immer ein Router ist.

    str(ipaddress.ip_interface('%s/%s'%(di['PLANT_IP'].strip(),24)).network[1])
    

    Das Datum der letzten erfolgreichen Aktualisierung wird im Inventar aufgezeichnet . In kontroversen Situationen hilft es zu verstehen, wie relevant die Informationen im System sind.

    #Записать текущую дату
    T = dt.date(dt.now()).strftime("%d %B %Y")
    shop['inventory']['date_hw_decomm'] = T
    

    Dann ist es sehr praktisch, die Statistiken zum Aktualisierungsdatum in den Inventardaten zu betrachten:



    Das wichtigste Feld - STATUS , "offen" - wird hinzugefügt und beginnt zu überwachen, jeder andere Status deaktiviert den Host. Wir löschen keine Objekte, um historische Daten und Statistiken zu erhalten.

    Nach den Tests musste ich die Ping-Funktion hinzufügen, um zu prüfen, ob der Host vor dem erstmaligen Hinzufügen erreichbar ist, weil In der Praxis stellten sich „offene“ Zustände ein , die noch nicht ganz offen, aber fast offen sind.

    def ping(ip):
        if os.system('ping -c 2 -W 1 %s > /dev/null'%ip) == 0:
            return True
        else:
            return False
    

    Früher hatte die Zabbix-API eine host.exist- Funktion , in neuen Versionen wurde sie jedoch mit host.get kombiniert . Wenn der Knoten vorhanden ist, gibt die Anforderung hostid in der zabbix-Datenbank zurück. Wenn nicht gefunden, wird 0 zurückgegeben. Zur Verifizierung musste ich jetzt existhost hinzufügen, aber tatsächlich ist es host.get .

    existhost.py
    #!/usr/bin/python3
    import sys, getopt
    from zabbix.api import ZabbixAPI
    def main(argv):
       global aname
       try:
          opts, args = getopt.getopt(argv,"hn:",["name="])
       except getopt.GetoptError:
          print('existhost.py -n ')
          sys.exit(2)
       for opt, arg in opts:
          if opt == '-h':
             print('existhost.py -n ')
             sys.exit()
          elif opt in ("-n", "--name"):
             aname = arg
    def exist(name):
       zapi = ZabbixAPI(url='http://z.noc.x5.ru/', user='user', password='pwd')
       hostget = zapi.host.get(search={'name':'%s'%name}, output='hostid')
       if hostget == []:
           return 0
       else:
           return int(hostget[0]['hostid'])
    if __name__ == "__main__":
            main(sys.argv[1:])
            print(exist(aname))
    


    Schließlich sammeln wir Informationen über die geleistete Arbeit, fügen sie den Protokollen hinzu, berichten und verschieben die verarbeitete Datei in das Repository in OLD.

    report.py
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    import smtplib, sys
    from email.mime.text import MIMEText    
    def report(message, subject):
    	me = 'zbx-scripts@x5.ru'
    	you = 'mail@x5.ru'
    	smtp_server = 'smtp.ru'
    	msg = MIMEText(message)
    	msg['Subject'] = subject
    	msg['From'] = me
    	msg['To'] = you
    	s = smtplib.SMTP(smtp_server)
    	s.sendmail(me, [you], msg.as_string())
    	s.quit()
    if __name__ == '__main__':
    	report(sys.argv[2], sys.argv[1])
    


    Im Allgemeinen ist die Überwachungsbasis bereit, führen Sie das Skript in cron für die automatische Ausführung aus und vergessen Sie es.



    Wie man Inventar füllt


    Wir sind nicht länger wir, wir sind Netzwerker.

    In der zweiten Phase werden die Objekte mit den Daten gefüllt, die die Ingenieure zum Arbeiten benötigen. Es ist notwendig, alle Daten zur Lösung des Vorfalls in einem System zu sehen, um nicht auf verschiedenen Systemen zu laufen und Informationen aus verschiedenen Quellen zu sammeln. Und da die wichtigsten technischen Daten in der Überwachung liegen, beziehen wir auch den Rest in die Überwachung ein.
    Um die erforderlichen Informationen zu sammeln und zu übertragen, hat Zabbix die Datei inventory.py geschrieben , die hauptsächlich SNMP- Daten von Geräten sammelt und in geringerem Umfang die Excel-Datei analysiert.

    Es stellt sich die Frage, warum man die eingebauten Gegenstände nicht verwendet und ihre Ergebnisse mit Zabbix selbst in das Inventar eingibt. Es gibt drei Antworten:

    1. Unzureichende Verschachtelung von Aktionen, wie Oft muss der Wert über SNMP abgerufen und das Ergebnis in der nächsten Abfrage verwendet werden.
    2. Die einmal tägliche Datenerfassung auf allen Knoten mit einem externen Skript lädt nicht die Hauptüberwachungsaktivität und es gibt keine Warteschlange für item'am
    3. Es gibt Daten, die nicht über SNMP erfasst werden können

    Daten zu Anbietern, auf die die Techniker der ersten und zweiten Linie nicht verzichten können, werden in einer Excel-Datei auf einem freigegebenen Netzlaufwerk gespeichert und von Managern aktualisiert, die Kommunikationsverträge abschließen. Die Integration in die Datei verursachte große Zweifel - Excel-Analyse, manuell ausgefüllt, die die Struktur, den Namen, den Speicherort usw. ändern kann, wird höchstwahrscheinlich ständig Fehler auslösen. Da es jedoch keine andere relevante Quelle für solche Daten gab, musste ich sie verwenden. Um uns irgendwie vor ständiger Überarbeitung des Skripts zu schützen, haben wir uns mit den Managern über die Struktur und die korrekte Befüllung geeinigt, erklärt, wie das automatische Entladen durchgeführt wird und dass es wichtig ist, die aktuelle Struktur zu beachten. In der Praxis sind natürlich Fehler aufgetreten, aber wir haben sie schnell verfolgt, verflucht, aber korrigiert.

    inventory.py
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    import sys, json, pysnmp, ipaddress, xlrd
    from datetime import datetime as dt
    from pysnmp.entity.rfc3413.oneliner import cmdgen
    def snmp(host, operation, *oid):
      generator = cmdgen.CommandGenerator()
      auth_data = cmdgen.UsmUserData('user', 'pwd', 'hash')
      transport = cmdgen.UdpTransportTarget((host, 161))
      getAtt = getattr(generator, '%sCmd'%operation)
      rst = (errorIndication, errorStatus, errorIndex, varBinds) = getAtt(auth_data, transport, *oid)
      if not errorIndication is None or errorStatus is True:
         return "Error: %s %s %s %s" % rst
      else:
         if operation=='get':
            return varBinds
         elif operation=='next':
            result=[]
            for var in varBinds:
               result.append(var)
            return result
    def xlsdata(file, sap):
      rb = xlrd.open_workbook(file)
      sheet = rb.sheet_by_index(0)
      base = {}
      for i in range(0, sheet.nrows-1):
         sapnum = str(round(sheet.cell(i,4).value)) if isinstance(sheet.cell(i,4).value,float) else sheet.cell(i,4).value
         name = str(round(sheet.cell(i,8).value)) if isinstance(sheet.cell(i,8).value,float) else sheet.cell(i,8).value
         if sap.upper() == sapnum.upper():
            base = {
              'type'		: (sheet.cell(i,2).value),
              'serialno_a'	: (sheet.cell(i,13).value),
              'serialno_b'	: (sheet.cell(i,20).value),
              'tag'		: ('2') if sheet.cell(i, 20).value != '' else ('1'),
              'macaddress_a'	: (sheet.cell(i, 15).value),
              'macaddress_b'	: (sheet.cell(i, 22).value)
            }
            base['date_hw_purchase'] = dt.date(dt.now()).strftime("%d %B %Y")
      return (base)
    def inventory(host, sap):
      BGPASBASE={}
      for line in open('/path/a.prokhorov/integration/BGP-AS-BASE.cfg'):
         if ':' in line:
            line = line.split(':')
            BGPASBASE[line[0]]='%s(%s)'%(line[1].rstrip(), line[0])
      ### Get Data from Operator
      shop = xlsdata('/mnt/oprf/providers_base.xlsx', sap)
      shop['date_hw_expiry'] = 'Failed'
      ### Get SNMP data
      shop['host_router'] = 'None'
      shop['host_netmask'] = 'None'
      shop['host_networks'] = 'None'
      try:
         ### Get Networks from router
         networks = ''
         for ip,mask in snmp(host, 'next', 'iso.3.6.1.2.1.4.20.1.1', 'iso.3.6.1.2.1.4.20.1.3'):
            networks = networks+str(ipaddress.ip_interface(u'%s/%s'%(ip[1].prettyPrint(), mask[1].prettyPrint())))+'\n'
         shop['host_networks']=networks
         ### Get BGP information
         bgppeers, ispnames = '',''
         for peer,asbgp in snmp(host, 'next', 'iso.3.6.1.2.1.15.3.1.7', 'iso.3.6.1.2.1.15.3.1.9'):
            asbgp = asbgp[1].prettyPrint()
            bgppeers = bgppeers+peer[1].prettyPrint()+'\n'
            ispnames = ispnames+(BGPASBASE.get(asbgp) if BGPASBASE.get(asbgp)!=None else asbgp)+'\n'
         shop['host_router'] = bgppeers.strip()[:38]
         shop['host_netmask'] = ispnames.strip()[:38]
         ### Get Vendor name and Model type
         hardware = snmp(host, 'get', 'iso.3.6.1.2.1.47.1.1.1.1.13.1', 'iso.3.6.1.2.1.47.1.1.1.1.10.1', 'iso.3.6.1.2.1.47.1.1.1.1.12.1', 'iso.3.6.1.2.1.1.1.0', 'iso.3.6.1.2.1.47.1.1.1.1.7.1')
         if str(hardware[0][1]) == '0235A325':
            shop['model'] = hardware[4][1].prettyPrint()
         else:
            shop['model'] = hardware[0][1].prettyPrint()
         shop['os_short'] = hardware[1][1].prettyPrint()
         shop['vendor'] = hardware[2][1].prettyPrint()
         version = hardware[3][1].prettyPrint()
         os = version.split('\n')[0]
         shop['os_full'] = version[:250]
         shop['os'] = ''.join(os.split(',')[:2])[:60]
         ### Make indicators
         shop['date_hw_expiry'] = 'Success'
         shop['date_hw_install'] = dt.date(dt.now()).strftime("%d %B %Y")
      except:
         shop.pop('host_router')
         shop.pop('host_netmask')
         shop.pop('host_networks')
      return shop
      #return json.dumps(dict([('inventory',shop)]), sort_keys=True, indent=4)
    if __name__ == "__main__":
      print(inventory(sys.argv[1], sys.argv[2]))
    

    BGP-AS-BASE.cfg
    3216:Beeline
    9002:Retn
    2854:Orange
    ~omit~
    8359:MTS


    Die Datei BGP-AS-BASE.cfg repräsentiert die Entsprechung von AS- Nummer und Name des Anbieters. Es ist erforderlich, den Anbieter zu bestimmen, bei dem BGP installiert ist (plötzlich liegt ein Fehler in der Datei mit den Verträgen vor). Die externe Basis wurde nicht verwendet, da es gibt viele private Räume der AS .

    In Bezug auf SNMP:

    • Wir fordern von den Router-Subnetzen nach OID 1.3.6.1.2.1.4.20.1.1 und Subnetzmasken nach OID 1.3.6.1.2.1.4.20.1.3 in einer Anfrage an. Wir verarbeiten es, übersetzen es in xxxx / xx und schreiben es in die Zelle host_networks .
    • Wenn wir Daten über die IP-Adressen von BGP- Peers sowie deren Lieferavis anfordern , finden wir den Anbieternamen anhand der Nummer in der von uns erstellten Datenbank. Wir schreiben sie in die Felder host_router und host_netmask . Es ist wichtig, sofort ein Limit von 38 Zeichen festzulegen, wie Diese Felder unterstützen nicht mehr. Wir haben die Namen der Felder in der Datenbank nicht immer mit den Daten übereinstimmen, die sie speichern, weil hat die vorhandenen Felder in der Zabbix-Datenbank verwendet, um keine Probleme beim Erstellen neuer Felder in der Tabelle zu haben. Die korrekten Feldnamen wurden im WEB korrigiert, es gab keine Verwirrung.
    • Wir laden Daten über den Hersteller, das Modell und die Software-Ausstattung hoch. Parsim, schreibe in die Variablen. Das Design, das mit dem Schreiben des Modells des Hardwareteils verbunden ist, hängt mit der Tatsache zusammen, dass bei einigen Modellen der Name von Cisco in einer anderen OID (meistens für das Gehäuse) geschrieben ist, sodass ich zusätzliche Datenüberprüfungen durchführen musste.

    Der gesamte mit SNMP verknüpfte Block ist in try-except eingeschlossen , sodass das Skript nicht ausfällt, wenn auf dem Gerät kein SNMP vorhanden ist, und wir zumindest Daten von den Anbietern aus Excel abrufen. Um zu verstehen, welcher Teil des Skripts abgeschlossen wurde und welcher nicht, notieren wir den Erfolg des SNMP-Blocks im Feld date_hw_expiry sowie das Datum, an dem das letzte Mal alle SNMP-Daten entfernt wurden, und das Datum, an dem die Daten das letzte Mal in der Excel-Datei gefunden wurden.


    All dies kommt in Form von JSON zurück , das für Zabbix bereit ist .

    Die Aktualisierung aller Inventardaten wird einmal täglich gestartet. Dabei werden alle Hosts entladen und die Datei inventory.py für jedes Objekt gestartet .

    mp-update.py
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    from multiprocessing import Pool
    import time
    from zabbix.api import ZabbixAPI
    from inventory import inventory
    from report import report
    def updating(shop):
      try:
        shop['inventory'] = inventory(shop['interfaces'][0]['ip'], shop['host'][-4:])
        shop.pop('interfaces')
        shop['inventory_mode'] = '1'
        shop.pop('host')
        print (shop['hostid'])
        return zapi.host.update(shop)
      except:
        print(">>>",shop['hostid'])
        with open ('/home/local/integration/error.txt', 'a') as err:
           err.write(shop['hostid'])
           err.write("\n")
    if __name__ =='__main__':
      t = time.time()
      zapi = ZabbixAPI(url='http://z.noc.x5.ru/', user='user', password='pwd')	
      shopbase = zapi.host.get(output=['host', 'hostid'], groupids= ['12', '13', '14'], monitored="1", selectInterfaces=['ip'])
      pool = Pool(processes=10)
      p=[0 for x in range(0,len(shopbase))]
      for i in range(0, len(shopbase), 10):
         print ("Index:", i,"\n",shopbase[i],"\n")
         pool.map(updating,shopbase[i:i+10])
      pool.close()
      pool.join()
      print(time.time()-t)
      report('Инвентарные данные обновлены в Zabbix.', 'Inventory updating succeed')	
    


    Multiprocessing wird verwendet (ein Beispiel aus den Weiten des Internets). Für die Suche verwenden wir die SAP-ID , die wir im Hostnamen haben. Die resultierende Ausgabe wird geschrieben, um 'Ohm in Zabbix zu aktualisieren .

    Zusammenfassung


    Für die Implementierung der gesamten Integration, die automatische Aktualisierung und die Aktualisierung der integrierten Mechanismen ist die Zabbix-API mehr als ausreichend. Die Hauptfunktionen sind host.get , host.create und host.update , mit denen Sie die Erstellung und Aktualisierung der Datenbank der Überwachungsobjekte vollständig steuern können. Die Eingabedaten dieser Funktionen können von allen verfügbaren Systemen und Quellen übermittelt werden.

    Die wichtigsten Python-Module, die uns bei dieser Aufgabe geholfen haben: pysnmp , xlrd , zabbix.api , xml , ipaddress , json .
    xlrd - Parsing Excel.
    xml - XML-Analyse.
    pysnmp - SNMP-Daten von Geräten abrufen .

    SNMP-Interaktion ist einfacher als SSH, zumindest weil die Hardware in der Praxis schneller auf SNMP reagiert als auf SSH. Das Parsen von SNMP-Antworten ist praktisch unnötig, obwohl sich die CLIs verschiedener Anbieter häufig stark voneinander unterscheiden und die Schlussfolgerungen gleich sind Die Teams können sich sogar bei verschiedenen Modellen desselben Herstellers unterscheiden.

    Die wichtigsten verwendeten OIDs :
    iso.3.6.1.2.1.4.20.1.1 - Adressen aller Router-Schnittstellen
    iso.3.6.1.2.1.4.20.1.3 - Subnetzmasken aller Router-Schnittstellen
    iso.3.6.1.2.1.15.3.1.7 - alle BGP-Peers des
    iso.3.6.1.2.1.15.3.1.9- Routers - AS aller BGP-Peers des iso.3.6.1.2.1.47.1.1.1.1.1.1- Routers
    - Modell
    iso.3.6.1.2.1.47.1.1.1.10.1 - Kurzversion der Software
    iso.3.6.1.2.1.47.1.1.1.1.12.1 - Hersteller
    iso.3.6.1.2.1.1.0 - Detaillierte Version der Software
    iso.3.6 .1.2.1.47.1.1.1.1.7.1 - Das Modell und die Art des Chassis-

    Dashboards mussten ein wenig ergänzt werden, um Probleme in Verteilungsnetzwerken zu trennen und sie nicht auf einem Haufen zu stören. Fügen Sie auch mehrere Felder hinzu, z. B. IP, Name und Adresse des Anbieters, damit es im Falle eines Massenunfalls ausreicht, alle Objekte mit einem Problem sofort mit allen für den Anbieter erforderlichen Daten aus dem Browser in die Nachricht einzufügen. "Workview"


    wurde separat geschrieben , in dem wir alle gesammelten Informationen sowie die für dieses Objekt gesammelten Grafiken finden.


    Jetzt auch beliebt: