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 Strich - darüber, wie Netzwerkmanager die Überwachung mit dem automatischen Hinzufügen von Netzwerkknoten implementiert haben, und ein wenig über die Schmerzen, die ich durchmachen musste.

Dieser Artikel konzentriert sich mehr auf Netzwerktechniker mit wenig Python-Erfahrung. Unterstützung bei der Automatisierung der Überwachung und Verbesserung der Lebens- und Arbeitsqualität, ohne dass die gesamte Objektflotte manuell aktualisiert werden muss.



Kurz gesagt, wir haben eine Überwachung aufgebaut


Hallo! Mein Name ist Alexander Prokhorov und zusammen mit dem Team von Netzwerktechnikern in unserer Abteilung arbeiten wir an einem Netzwerk in # ITX5. Unsere Abteilung entwickelt Netzwerkinfrastruktur, Netzwerküberwachung und Automatisierung. Ja, und alles, was mit Datenübertragung zu tun hat.



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

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

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

Wir haben 14.000 Einzelhandelsimmobilien und die erste Aufgabe, die wir gelöst haben, war die Bestimmung unzugänglicher Objekte, ihrer Anzahl und geografischen Verteilung.

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

Lange Geschichte.
Alles begann mit der Installation der Überwachung auf einem Computer unter dem Tisch ...

Als ich 2013 für das Unternehmen arbeitete, hatten wir keine Netzwerküberwachung, obwohl das Netzwerk selbst zu dieser Zeit groß war, ungefähr 4000 Objekte. Wir haben von massiven (und nicht so) Stürzen am häufigsten durch den Lawinenempfang von Anträgen, Benutzern oder anderen Abteilungen erfahren.



Das erste wurde Zabbix 1.8 als ein Produkt mit zunehmender Dynamik (modisch, modern, jugendlich) installiert, das leicht und erschwinglich ist, um Open Source mit einer großen Community zu installieren. 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 installierten es auf dem Computer "unter dem Tisch". Redundanzstufe - USV.

Die Hauptfrage nach der Installation ist, wie alle Objekte (4k!) In die Überwachung eingefügt werden und gleichzeitig Anwendungen erstellt werden können, 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 es wurde nicht angezeigt), und es wurde beschlossen, den Objektrouter als Netzwerkknoten hochzuladen. Weitere Netzwerkgeräte wurden nicht gesteuert (bereits verwaltet).

Das Parsen unserer Datei mit Netzwerkhosts (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. Die Aktualisierung wurde alle drei Monate durchgeführt, wobei die geschlossenen Objekte entfernt und neue hinzugefügt wurden. Im Laufe der Zeit stellte sich heraus, dass Zabbix für uns und die Hotline zur wichtigsten und einzigen Informationsquelle für die Verfügbarkeit von Einrichtungen und vor allem für Massenstürze wurde. Dies ermöglichte es der Hotline, sich auch nachts über Massenunfälle zu informieren und Ingenieure mit Anrufen zu wecken (übrigens, wenn niemand davon wusste, war es einfacher zu leben). Nicht immer nächtliche Stromausfälle im Büro ermöglichten es der USV, die Überwachung unseres Netzwerks angemessen aufrechtzuerhalten. Irgendwann begannen wir Backups zu machen. Weil Die Überwachung war instabil und zeitweise. Die Unternehmen beschlossen, eine Gruppe zu organisieren, die sich ausschließlich dieser Aufgabe widmete. Sehr bald begann sie mit der Implementierung eines zentralisierten Zabbix, der nicht nur das Netzwerk überprüft.

Unser alter Zabbix lebte weiterhin unter dem Tisch. Nachdem ich eine bestimmte Anzahl von Elementen hinzugefügt hatte, 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 und sie alle ins Kreuz setzen musste, damit die eigentliche Reservierung (und der Platz unter dem Tisch vorbei war). . Das Leben darin wurde unterstützt, um der Überwachung und Beobachtung schnell benutzerdefinierte Parameter hinzuzufügen. Im Übrigen sind wir zu einem zentralen umgezogen.

Die zentrale Überwachung war für alle IT-Geräte zuständig - Router, Server, Registrierkassen, Terminals. Nach einer Weile überwuchs er mit einer großen Anzahl von Gegenständen. Um auf wertvolle Informationen zur Barrierefreiheit zuzugreifen, musste man etwas warten, vielleicht sogar einen Kaffee trinken. Darüber hinaus stellten wir immer mehr Anforderungen an eine spezifischere und individuellere Netzwerküberwachung. Da wir zu diesem Zeitpunkt einige Erfahrungen mit dem System gesammelt hatten, entschieden wir uns, die alte Implementierung von Grund auf neu zu erstellen, aber zu Recht - unter dem Namen zabbix.noc.x5.ru. Sie befand sich im Rechenzentrum und implementierte die erforderlichen Funktionen selbst. Ü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, den Empfehlungen auf zabbix.com für eine große und sehr große Implementierung zu folgen.

Das erste Problem, mit dem wir konfrontiert waren, war das automatische Hinzufügen von Netzwerkknoten zur Überwachung. Die regelmäßige Entdeckung verschwand sofort. Unser Netzwerkangebot befindet sich auf allen Freiflächen des Supernets 10/8. Viele Adressen müssten abgefragt werden, und die automatische Erkennung würde viele Systemressourcen beanspruchen, würde jedoch 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 Handelsobjekten wurden in der im Unternehmen verwendeten SAP gefunden. Der synchronisierte Zugriff auf den Webdienst zum Hochladen von Daten direkt aus SAP wurde nicht ausgeführt. Die Anforderung für alle Objekte dauerte eine Weile. Asynchronen Anruf getätigt. Genau um Mitternacht wird der vollständige Upload von SAP in Form von XML zu ftp hinzugefügt, und tagsüber fallen XML -Dateien mit Abweichungen von den neuesten Versionen darauf.

Zabbix verwendete die Zabbix-API zum Laden von Daten und interagierte mit ihr über Python .

In der ersten Phase wurde der Datensatz ermittelt, den wir zum Erstellen des Objekts benötigten. Wir verwenden alle erhaltenen Zeichen zur korrekten Klassifizierung eines Objekts im System oder zur weiteren Bequemlichkeit. 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 werden
  • Ort - physikalische Adresse
  • Telefon - Kontakttelefon
  • Gruppen - Diese Gruppe von Gruppen wird basierend auf dem Typ und der Position des Objekts gebildet



Sap-sync.py-Modul


XML von SAP
<?xml version="1.0" encoding="ISO-8859-1"?> <werks> <WERKS>1234</WERKS> <NAME1>4321-</NAME1> <PLANT_IP>192.168.1.50</PLANT_IP> <REGION>31</REGION> <PSTLZ>308580</PSTLZ> <CITY1>.</CITY1> <CITY2> .</CITY2> <STREET> .</STREET> <HOUSE_NUM1>1</HOUSE_NUM1> <TEL_NUMBER>(999)777-77-77</TEL_NUMBER> <BRANCH>CH</BRANCH> <REGION>CH_MSK</REGION> <REGION_NAME> </REGION_NAME> <FORMAT>CH_MSK_D</FORMAT> <STATUS> </STATUS> </werks> 


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 <path>') sys.exit(2) for opt, arg in opts: if opt == '-h': print('sync-sap-chg.py -p <path>') 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 ist das XML- Parsing und die JSON- Übersetzung für die Zabbix-API. In diesem Fall ist es sehr praktisch, Python-Wörterbücher wie zu verwenden Sie müssen nicht zusätzlich formatiert werden. Mit dem Modul zabbix.api können Sie ihm einfach ein Wörterbuch mit der richtigen Struktur zuführen. JSON mit der 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 Adresse des Servers gespeichert, nicht der Router, aber unter Verwendung des IP-Adressmoduls 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 umstrittenen 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, Statistiken zum Aktualisierungsdatum in den Inventardaten anzuzeigen:



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 überprüfen, ob der Host vor dem ersten Hinzufügen zugänglich ist, weil In der Praxis tauchten „offene“ Status auf, die noch nicht ganz offen sind, aber fast.

 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 die Host- ID in der zabbix-Datenbank zurück. Wenn nicht gefunden, wird 0 zurückgegeben. Zur Überprüfung 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 <name>') sys.exit(2) for opt, arg in opts: if opt == '-h': print('existhost.py -n <name>') 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 und Berichten hinzu 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.



So füllen Sie das Inventar


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

In der zweiten Phase werden Objekte mit Daten gefüllt, die Ingenieure zum Arbeiten benötigen. Es ist erforderlich, alle Daten zur Lösung des Vorfalls in einem System anzuzeigen, um nicht über verschiedene Systeme hinweg zu laufen und Informationen in Teilen aus verschiedenen Quellen zu sammeln. Und da die wichtigsten technischen Daten in der Überwachung liegen, ziehen wir auch den Rest in die Überwachung ein.
Um die erforderlichen Informationen zu sammeln und zu übertragen, hat Zabbix inventar.py geschrieben , das sich hauptsächlich mit dem Sammeln von SNMP- Daten von Geräten und in geringerem Umfang mit dem Parsen der Excel-Datei befasst.

Die Frage lautet: Warum nicht die eingebauten Gegenstände verwenden und ihr Ergebnis mit den Werkzeugen von Zabbix selbst in das Inventar eingeben? Es gibt drei Antworten:

  1. Unzureichende Verschachtelung von Aktionen, z Es ist häufig erforderlich, den Wert über SNMP abzurufen und das Ergebnis in der nächsten Abfrage zu verwenden.
  2. Wenn die Datenerfassung einmal täglich auf allen Knoten mit einem externen Skript ausgeführt wird, wird die Hauptüberwachungsaktivität nicht geladen, 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 Ingenieure der ersten und zweiten Linie nicht verzichten können, werden in einer Excel-Datei auf einem gemeinsam genutzten Netzlaufwerk gespeichert und von Managern aktualisiert, die Kommunikationsverträge abschließen. Die Integration in die Datei verursachte große Zweifel - eine manuell ausgefüllte Excel-Analyse, die die Struktur, den Namen, den Speicherort usw. ändern kann, führt höchstwahrscheinlich ständig zu Fehlern. Da es jedoch keine andere relevante Quelle für solche Daten gab, musste ich sie verwenden. Um uns irgendwie vor einer ständigen Bearbeitung 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.

inventar.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 der AS- Nummer und des Anbieternamens. Es muss der Anbieter ermittelt werden, 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 AS- Nummern.

In Bezug auf SNMP :

  • Wir fordern von den Router-Subnetzen durch OID 1.3.6.1.2.1.4.20.1.1 und Subnetzmasken von 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 .
  • Wir fordern Daten zu den IP-Adressen der BGP- Peers sowie deren Lieferavis an . Wir finden den Anbieternamen nach 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 Diese Felder unterstützen nicht mehr. Unsere Feldnamen in der Datenbank stimmen nicht immer mit den Daten überein, die sie speichern, weil hat die vorhandenen Felder in der Zabbix-Datenbank verwendet, um nicht mit dem Erstellen neuer Felder in der Tabelle herumzuspielen. Die korrekten Feldnamen wurden im WEB korrigiert, es gab keine Verwirrung.
  • Wir laden Daten über den Hersteller, das Modell und die Softwareausrüstung hoch. Parsim, schreibe in die Variablen. Das mit dem Schreiben des Hardwaremodells verbundene Design beruht auf der Tatsache, dass Cisco bei einigen Modellen einen Namen in einer anderen OID geschrieben hat (meistens für das Gehäuse), sodass ich eine zusätzliche Datenprüfung durchführen musste.

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


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

Das Aktualisieren aller Inventardaten wird einmal täglich gestartet, alle Hosts entladen und die Datei inventar.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 stammt aus den Weiten des Internets). Für die Suche verwenden wir die SAP-ID , die wir im Hostnamen haben. Die resultierende Ausgabe ist Update 'Ohm in Zabbix geschrieben.

Zusammenfassung


Für die Implementierung der gesamten Integration, automatischen Aktualisierung und Aktualisierung der integrierten Mechanismen ist die Zabbix-API mehr als ausreichend. Die Hauptfunktionen sind host.get , host.create und host.update , mit denen Sie zusammen die Erstellung und Aktualisierung der Datenbank mit Überwachungsobjekten 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 der Bewältigung dieser Aufgabe geholfen haben: pysnmp , xlrd , zabbix.api , xml , ipaddress , json .
xlrd - Parsing Excel.
xml - XML-Analyse.
pysnmp - Abrufen von SNMP-Daten von Geräten.

Die SNMP-Interaktion ist einfacher als bei SSH, zumindest weil die Hardware in der Praxis schneller auf SNMP als auf SSH reagiert. Das Parsen von SNMP-Antworten ist praktisch nicht erforderlich, obwohl die CLIs verschiedener Anbieter häufig sehr unterschiedlich sind und die Schlussfolgerungen dieselben sind Teams können sich sogar in verschiedenen Modellen desselben Anbieters unterscheiden.

Die wichtigsten angewendeten 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 Routers
iso.3.6.1.2.1.15.3.1.9 - AS aller BGP-Peers des Routers
iso.3.6.1.2.1.47.1.1.1.1.13.1 - Modell
iso.3.6.1.2.1.47.1.1.1.1.10.1 - Kurzversion der Software
iso.3.6.1.2.1.47.1.1.1.1.1.12.1 - Anbieter
iso.3.6.1.2.1.1.1.0 - detaillierte Softwareversion
iso.3.6.1.2.1.47.1.1.1.1.7.1 - Modell, Gehäusetyp

Das Dashboard musste ein wenig hinzugefügt werden, um Probleme in Verteilungsnetzwerken aufzuteilen und sie nicht auf einem Haufen zu stören. Fügen Sie außerdem mehrere Felder hinzu, z. B. IP, Name und Adresse des Anbieters, damit im Falle eines Massenunfalls alle Objekte mit einem Problem sofort mit allen für den Anbieter erforderlichen Daten aus dem Browser in die Nachricht kopiert und eingefügt werden können.


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

Source: https://habr.com/ru/post/de438754/


All Articles