Cómo hicimos el monitoreo de red para 14,000 objetos

Teníamos 14,000 objetos, zabbix, api, python y una renuencia a agregar objetos a mano. Debajo del corte, sobre cómo los administradores de red implementaron el monitoreo con la adición automática de nodos de red, y un poco sobre el dolor por el que tuve que pasar.

Este artículo se centra más en ingenieros de redes con poca experiencia en python. Para ayudar con la automatización del monitoreo y la mejora de la calidad de vida y el trabajo, en ausencia de la necesidad de actualizar manualmente toda la flota de objetos.



Larga historia corta, hemos construido un monitoreo


Hola Mi nombre es Alexander Prokhorov y, junto con el equipo de ingenieros de redes de nuestro departamento, estamos trabajando en una red en # ITX5. Nuestro departamento desarrolla infraestructura de red, monitoreo de redes y automatización. Sí, y todo lo relacionado con la transferencia de datos.



Rompería el sistema de monitoreo en 5 subtareas:

  • Descargar datos maestros
  • Obtención de información sobre el estado de los objetos.
  • Disparadores y Alertas
  • Informes
  • Visualización

En este artículo nos gustaría compartir cómo hicimos la integración de monitoreo con datos maestros en nuestra empresa.

Tenemos 14,000 propiedades comerciales, y la primera tarea que resolvimos fue la determinación de objetos inaccesibles, su número y distribución geográfica.

El monitoreo se realizó en Zabbix . En pocas palabras, por qué: suerte y legado. El resto:

Larga historia
Todo comenzó con la instalación de monitoreo en una computadora debajo de la mesa ...

Cuando vine a trabajar para la compañía en 2013, no teníamos monitoreo de red, aunque la red, incluso en ese momento, era grande, alrededor de 4000 objetos. Aprendimos sobre caídas masivas (y no tan frecuentes) a partir de la recepción de aplicaciones, usuarios o de otros departamentos como avalanchas.



El primero se instaló Zabbix 1.8, como un producto que gana impulso (moderno, moderno, juvenil), liviano y asequible para instalar de código abierto con una gran comunidad. Tuvimos suerte con la elección.

No hubo recursos para la instalación, nadie solicitó. No estaba claro si esto funcionaría en absoluto; nadie tenía experiencia en implementación. Pero lo necesitábamos, y lo instalamos en la computadora "debajo de la mesa". Nivel de redundancia - UPS.

La pregunta principal después de la instalación es cómo verter todos los objetos (¡4k!) En la supervisión y, al mismo tiempo, lograr crear aplicaciones que ya estén bloqueadas en Remedy. Zabbix ya admitía la importación / exportación de xml con datos en hosts. El número de objetos es grande, no tenía sentido crear un grupo separado para el objeto (y no apareció), y se decidió cargar el enrutador de objetos como un nodo de red. Más del equipo de red no estaba controlado (ya administrado).

Se realizó el análisis de nuestro archivo con los hosts de red (IPAM en Excel) y se volvió a formatear en xml, que Zabbix acepta digerir. No es la primera vez, pero todos los hosts se cargaron, la actualización se realizó una vez cada tres meses, eliminando los objetos cerrados y agregando otros nuevos. Con el tiempo, resultó que Zabbix se convirtió en la principal y única fuente de información para nosotros y la línea directa sobre la disponibilidad de instalaciones y, lo más importante, sobre caídas masivas. Esto permitió que la línea directa se enterara de accidentes masivos incluso de noche y despertara a los ingenieros con llamadas (por cierto, cuando nadie lo sabía, era más fácil vivir). No siempre los cortes de energía nocturnos en la oficina permitieron que el UPS mantenga adecuadamente el monitoreo de nuestra red. En algún momento, comenzamos a hacer copias de seguridad. Porque El monitoreo era inestable e intermitente, las compañías decidieron organizar un grupo dedicado exclusivamente a esta tarea. Muy pronto, comenzó a implementar un Zabbix centralizado, que verifica no solo la red.

Nuestro viejo Zabbix continuó viviendo debajo de la mesa. Después de agregar una cierta cantidad de elementos, la base de datos comenzó a disminuir un poco, la web, la cola y el retraso en el sondeo crecieron, así que pronto tuve que obtener dos computadoras más como proxy y ponerlas todas en la cruz, para que la reserva real (y el lugar debajo de la mesa terminara) . Se admitió la vida en él para agregar rápidamente algún tipo de parámetro personalizado para monitorearlo y observarlo. Por lo demás, nos mudamos a una centralizada.

El monitoreo centralizado estuvo a cargo de todos los equipos de TI: enrutadores, servidores, cajas registradoras, terminales. Después de un tiempo, creció con una gran cantidad de artículos. Para acceder a información invaluable de accesibilidad, tuvo que esperar un poco, tal vez incluso tomar un café. Además, teníamos más y más requisitos para un monitoreo de red más específico y personalizado. Teniendo en ese momento algo de experiencia trabajando con el sistema, decidimos hacer la implementación anterior desde cero, pero con razón, bajo el nombre de zabbix.noc.x5.ru, estaba ubicada en el centro de datos con la implementación de las funciones necesarias por nosotros mismos. Sobre esta introducción y el cuerpo principal del artículo.

La versión de Zabbix es 3.0 LTS . Actualizado solo dentro de las versiones LTS.

Configuración - 4 máquinas virtuales: servidor + base de datos, proxy, proxy, web

Por recursos, intentamos seguir las recomendaciones en zabbix.com para una implementación grande y muy grande.

El primer problema al que nos enfrentamos fue la adición automática de nodos de red a la supervisión. Descubrimiento regular desapareció de inmediato. Nuestra gama de redes se encuentra en todos los espacios abiertos de la superred 10/8. Tendrían que sondearse muchas direcciones y el descubrimiento automático ocuparía muchos recursos del sistema, pero no resolvería el problema de agregar información no técnica sobre un objeto.

Cómo agregar objetos


La solución fue usar scripts externos para agregar objetos. Los datos maestros sobre objetos comerciales se encontraron en el SAP utilizado en la empresa. El acceso sincronizado al servicio web para cargar datos directamente desde SAP no salió, la solicitud de todos los objetos tomó bastante tiempo. Hizo una llamada asincrónica. Exactamente a la medianoche, la exportación completa de SAP se agrega a ftp en forma de XML , y durante el día recae sobre XML con diferencias de las últimas versiones.

Zabbix usó la API de Zabbix para cargar datos e interactuó con ella desde Python .

En la primera etapa, se determinó el conjunto de datos que necesitábamos para crear el objeto. Utilizamos todos los signos obtenidos para la clasificación correcta de un objeto en el sistema o para mayor comodidad. Estos signos incluyen:

  • Dirección IP : el campo más importante para crear una interfaz de monitoreo
  • ID de SAP : tenemos un identificador de objeto único
  • Estado : abierto / cerrado
  • Nombre : el nombre o el número del objeto, que los usuarios suelen utilizar al contactar
  • Ubicación : dirección física
  • Teléfono - teléfono de contacto
  • Grupos : este grupo de grupos se forma según el tipo y la ubicación del objeto



Módulo Sap-sync.py


XML de 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) 


El objetivo principal de este módulo es el análisis XML y la traducción JSON para la API de Zabbix. Es muy conveniente en este caso utilizar diccionarios de Python, ya que no es necesario formatearlos adicionalmente: con el módulo zabbix.api , simplemente puede darle un diccionario con la estructura correcta. JSON con la estructura se ve así:

 { 'host': 'Hostname' 'groups': [...] 'interfaces': [{},{},{}] 'inventory': {} 'templates': [{},{},{}] 'inventory_mode': '1' 'proxy_hostid': 'INT' 'status': '0' } [] -  {} -  

En nuestro campo con la dirección IP en SAP, la dirección del servidor se almacena, no el enrutador, pero usando el módulo ipaddress consideramos la primera dirección de subred, que en nuestro caso siempre es un enrutador.

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

La fecha de la última actualización exitosa se registra en el Inventario , en situaciones controvertidas ayuda a comprender qué tan relevante es la información en el sistema.

 #   T = dt.date(dt.now()).strftime("%d %B %Y") shop['inventory']['date_hw_decomm'] = T 

Entonces es muy conveniente mirar las estadísticas sobre la fecha de actualización en los datos del inventario:



El campo más importante - ESTADO , "abierto" - se agrega y comienza a ser monitoreado, cualquier otro estado - desactiva el host. No eliminamos objetos para preservar datos históricos y estadísticas.

Después de las pruebas, tuve que agregar la función ping para verificar si el host es accesible antes de la adición inicial, porque en la práctica, comenzaron a aparecer estados "abiertos" , que aún no están abiertos, pero casi.

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

Anteriormente, la API de Zabbix tenía una función host.exist , pero en las nuevas versiones se combinaba con host.get . Si el nodo existe, la solicitud devuelve hostid en la base de datos zabbix. Si no se encuentra, devuelve 0. Para la verificación, ahora tenía que agregar existhost , pero de hecho 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)) 


Finalmente, recopilamos información sobre el trabajo realizado, la agregamos a los registros, informes y movemos el archivo procesado al repositorio en 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]) 


En general, la base de monitoreo está lista, ejecuta el script en cron para la ejecución automática y olvídalo.



Cómo llenar inventario


Ya no somos nosotros, somos networkers.

La segunda etapa es llenar objetos con datos que los ingenieros necesitan para trabajar. Es necesario ver todos los datos para resolver el incidente en un sistema, para no correr en diferentes sistemas, recolectando información en partes de diferentes fuentes. Y dado que los datos técnicos principales están en el monitoreo, también dibujamos el resto en el monitoreo.
Para recopilar y transmitir la información necesaria, Zabbix escribió Inventory.py , que se dedica principalmente a recopilar datos SNMP del equipo y, en menor medida, a analizar el archivo Excel.

La pregunta comienza: ¿por qué no utilizar los elementos integrados e ingresar su resultado en el inventario utilizando las herramientas de Zabbix? Hay tres respuestas:

  1. Anidación insuficiente de acciones, como a menudo es necesario extraer el valor sobre SNMP y usar el resultado en la siguiente consulta.
  2. La ejecución de una recopilación de datos una vez al día en todos los nodos con un script externo no carga la actividad de monitoreo principal y no hay cola para item'am
  3. Hay datos que no se pueden recopilar a través de SNMP

Los datos sobre los proveedores, de los cuales los ingenieros de primera y segunda línea no pueden prescindir, se almacenan en un archivo de Excel en una unidad de red compartida y los gerentes que realizan contratos de comunicaciones los actualizan. La integración con el archivo causó grandes dudas: el análisis de Excel, completado manualmente, que puede cambiar la estructura, el nombre, la ubicación, etc., probablemente arrojará errores constantemente. Pero debido a la falta de otra fuente relevante de dichos datos, tuve que usarlo. Para protegernos de alguna manera de la edición constante del script, acordamos con los gerentes sobre la estructura y el llenado correcto, explicamos cómo se realizará la descarga automática y que es importante observar la estructura actual. En la práctica, por supuesto, se produjeron errores, pero los rastreamos rápidamente, los maldecimos, pero los corregimos.

inventario.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


El archivo BGP-AS-BASE.cfg representa la correspondencia del número AS y el nombre del proveedor. Es necesario determinar el proveedor con el que está instalado BGP (de repente hay un error en el archivo con los contratos). La base externa no se utilizó, ya que Hay muchos números AS privados.

En términos de SNMP :

  • solicitamos de las subredes del enrutador por OID 1.3.6.1.2.1.4.20.1.1 y máscaras de subred por OID 1.3.6.1.2.1.4.20.1.3 en una solicitud. Lo procesamos, lo traducimos a xxxx / xx y lo escribimos en la celda host_networks .
  • Solicitamos datos sobre las direcciones IP de los pares de BGP , así como su ASN , encontramos el nombre del proveedor por número en la base de datos que creamos. Los escribimos en los campos host_router y host_netmask . Es importante establecer de inmediato un límite de 38 caracteres, ya que Estos campos no admiten más. Nuestros nombres de campo en la base de datos no siempre coinciden con los datos que almacenan, porque utilizó los campos existentes en la base de datos Zabbix, para no meterse con la creación de nuevos campos en la tabla. Los nombres de campo correctos fueron corregidos en la WEB, no hubo confusión.
  • cargamos datos sobre el proveedor, modelo y equipo de software. Parsim, escribe a las variables. El diseño asociado con la escritura del modelo del hardware se debe al hecho de que para algunos modelos Cisco tiene un nombre escrito en un OID diferente (con mayor frecuencia para el chasis), por lo que tuve que hacer una verificación de datos adicional.

Todo el bloque asociado con SNMP está encerrado en try-except , de modo que si no hay SNMP en el equipo, el script no se cae, y al menos obtenemos datos de Excel por parte de los proveedores. Para comprender qué parte del script se ha completado y cuál no, escribimos el éxito del bloque SNMP en el campo date_hw_expiry , además de la fecha en que la última vez que pudimos eliminar todos los datos de SNMP y la fecha en que fue la última vez que pudimos encontrar los datos en el archivo de Excel.


Todo esto vuelve en forma de JSON listo para Zabbix.

La actualización de todos los datos de inventario se inicia una vez al día, descargando todos los hosts e iniciando Inventory.py para cada objeto.

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') 


Se utiliza el multiprocesamiento (se toma un ejemplo de las vastas extensiones de Internet). Para buscar, utilizamos la ID de SAP , que tenemos en el nombre del host. El resultado resultante es la actualización escrita 'ohm en Zabbix.

Resumen


Para la implementación de toda la integración, actualización automática y actualización de los mecanismos integrados, la API de Zabbix es más que suficiente. Las funciones principales utilizadas son host.get , host.create y host.update , que juntas le permiten controlar completamente la creación y actualización de la base de datos de objetos de monitoreo. Los datos de entrada de estas funciones pueden enviarse desde cualquier sistema y fuente disponible.

Los principales módulos de Python que nos ayudaron a hacer frente a esta tarea: pysnmp , xlrd , zabbix.api , xml , ipaddress , json .
xlrd : análisis de Excel.
xml : análisis XML.
pysnmp : extracción de datos SNMP del equipo.

La interacción SNMP es más fácil que SSH, al menos porque en la práctica la pieza de hardware responde más rápidamente a SNMP que a SSH, analizar las respuestas SNMP es prácticamente innecesario, aunque las CLI de diferentes proveedores a menudo son muy diferentes entre sí, y las conclusiones son las mismas. los equipos pueden diferir incluso en diferentes modelos del mismo proveedor.

Los principales OID aplicados:
iso.3.6.1.2.1.4.20.1.1 : direcciones de todas las interfaces de enrutador
iso.3.6.1.2.1.4.20.1.3 : máscaras de subred de todas las interfaces de enrutador
iso.3.6.1.2.1.15.3.1.7 - todos los pares BGP del enrutador
iso.3.6.1.2.1.15.3.1.9 - AS de todos los pares BGP del enrutador
iso.3.6.1.2.1.47.1.1.1.1.13.1 - modelo
iso.3.6.1.2.1.47.1.1.1.1.10.1 - versión corta del software
iso.3.6.1.2.1.47.1.1.1.1.1.12.1 - proveedor
iso.3.6.1.2.1.1.1.0 - versión detallada del software
iso.3.6.1.2.1.47.1.1.1.1.7.1 - modelo, tipo de chasis

Dashboard tuvo que agregarse un poco para dividir los problemas en las redes de distribución y no interferir con ellos en un montón. Agregue también varios campos, por ejemplo, ip, nombre y dirección del proveedor, de modo que en caso de un accidente masivo sería suficiente copiar y pegar del navegador en el mensaje todos los objetos con un problema, inmediatamente con todos los datos necesarios para el proveedor.


"Workview" se escribió por separado , en el que podemos encontrar toda la información recopilada, además de los gráficos que se recopilan para este objeto.

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


All Articles