Архив метки: python

Вывод списка неподдерживаемых элементов данных Zabbix скриптом

Задачу можно решить скриптом на python:

#!/usr/local/bin/python
# coding=utf-8

import socket
import re
from pyzabbix import ZabbixAPI
import time
import requests
requests.packages.urllib3.disable_warnings()

zapi = ZabbixAPI("https://укауц.укаукацук.ru")
zapi.session.verify = False
zapi.login("укацука", "уцкацукацука")


hosts = zapi.host.get();
for hs in hosts:        
    triggers = zapi.item.get(hostids=[hs["hostid"]],);
    for tr in triggers:
        if tr["state"]=="1" and tr["status"]=="0":         
         print hs["hostid"],"|",hs["host"],"|",tr["itemid"].encode('utf8'),"|",tr["name"].encode('utf8');

Новый проект. DHCP сервер с выборкой из БД на Python

Задачей было написать аналог проекта DHCP2DB , но только на Python вместо C.

В принципе уже как прототип работает. Может отдавать IP адрес как обычным устройствам, так и свичам работающим по опции 82.

Ссылка на GIT: https://github.com/donpadlo/dhcp2dbpy

Telnet клиент на Python

Например можно реализовать так:

import getpass
import sys
import telnetlib

HOST = "21.211.37.17"
user = "уцкаыукn";
password = "ц45пукпу"

def teln(num):
    tn = telnetlib.Telnet(HOST)
    tn.set_debuglevel(0)
    tn.read_until("Username:")
    tn.write(user + "\r")
    tn.read_until("word:")
    tn.write(password + "\r")    
    tn.write("show olt "+str(num)+" optical-online-onu\r  ")
    tn.read_until("epon#")
    tn.write("logout\r")
    print tn.read_all()
    tn.close()

teln(1)
teln(2)
teln(3)
teln(4)

Пример простого DHCP сервера на Python

В целях самообразования, написал скрипт на Python, который выдает запрашивающему IP адрес. Всё жестко прибито гвоздями. Делал для изучения работы DHCP /  Python не более того.

#!/usr/bin/env python3
# coding=utf-8
# Сервер DHCP на Python 3.5 с коннектором к БД MySQL
# Данный код создан и распространяется по лицензии GPL v3
# Изначальный автор данного кода - Грибов Павел
# http://грибовы.рф

import socket
import dhcp_parse_packet
from pprint import pprint
import threading

HOST = '0.0.0.0'    # какой интерфейс слушаем
PORT_IN = 67        # входящие пакеты UDP DHCP
PORT_OUT = 68       # исходящие пакеты UDP DHCP
LeaseTime=8600      # время жизни IP адреса
ThreadLimit=10      # количество потоков для обработки запросов

udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP)
udp_socket.bind((HOST,PORT_IN))


def PacketWork(data,addr): 
    packet=dhcp_parse_packet.parsepacketIn(data)
    print("Пришел пакет:")
    pprint(packet)
    print("Address:")    
    pprint(addr)    
    if packet["op"]=="DHCPDISCOVER":
        print("--что нужно ответить этому товарищу...");
        packetoffer=dhcp_parse_packet.CreateDHCPOFFER(packet)
        print ("--делаем ему DHCPOFFER (выгодное предложение)")
        pprint(packetoffer)
        udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        rz=udp_socket.sendto(packetoffer, ("255.255.255.255",68))
        #pprint(rz)
        print("-ответили!");
        #verify=dhcp_parse_packet.parsepacketIn(packetoffer)
        #pprint(verify)
    if packet["op"]=="DHCPREQUEST":        
        print ("-- ура, господин выбрал меня любимой женой..и запрашивает IP адрес, который я уже предлагал..");
        print (packet["RequestedIpAddress"])
        print ("--делаем ему DHCPACK (да, всё так!)")
        packetack=dhcp_parse_packet.CreateDHCPACK(packet)
        pprint(packetack)
        udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        rz=udp_socket.sendto(packetack, ("255.255.255.255",68))
        
while True:
    data, addr = udp_socket.recvfrom(65000)
    print ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Новый UDP пакет пришел !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")    
    thread = threading.Thread(target=PacketWork, args=(data,addr,)).start()	
    while threading.active_count() >ThreadLimit:
       time.sleep(1)           
  
udp_socket.close()

dhcp_parse_packet.py:

# coding=utf-8
# Сервер DHCP на Python 3.5 с коннектором к БД MySQL
# Данный код создан и распространяется по лицензии GPL v3
# Изначальный автор данного кода - Грибов Павел
# http://грибовы.рф

import socket
from struct import *
from pprint import pprint

# парсим входящий пакет
def parsepacketIn(data): 
 try:
    print("Len data:",len(data))
    op="unknown"
    if data[0]==1: op="DHCPDISCOVER/DHCPREQUEST";
    if data[0]==2: op="DHCPOFFER/DHCPACK";    
    if data[1]==1: htype="MAC" 
    else : htype="unknown"    
    hlen=data[2]
    hops=data[3]
    xidhex=hex(data[4])[2:]+hex(data[5])[2:]+hex(data[6])[2:]+hex(data[7])[2:]
    xidbyte=data[4:8]
    secs=data[8]*256+data[9];
    flags=pack('BB',data[10],data[11])
    ciaddr=socket.inet_ntoa(pack('BBBB',data[12],data[13],data[14],data[15]));    
    siaddr=socket.inet_ntoa(pack('BBBB',data[16],data[17],data[18],data[19]));    
    giaddr=socket.inet_ntoa(pack('BBBB',data[20],data[21],data[22],data[23]));   
    chaddr=data[28:34].hex()
    magic_cookie=data[236:240]    
    print("Magic:",magic_cookie[0],magic_cookie[1],magic_cookie[2],magic_cookie[3])
    res={"op":op,"htype":htype,"hlen":hlen,"hops":hops,"xidbyte":xidbyte,"xidhex":xidhex,"secs":secs,"flags":flags,"ciaddr":ciaddr,"siaddr":siaddr,"giaddr":giaddr,"chaddr":chaddr,"magic_cookie":magic_cookie}        
    if magic_cookie==b'c\x82Sc':                
        # парсим опции
        print("--парсим опции");
        options=data[240:len(data)]
        print("Options:",options);        
        res["gpoz"]=240;
        while res["gpoz"]<len(data):
            print("Option:",data[res["gpoz"]]," hex",hex(data[res["gpoz"]])[2:])
            res=FindOptions(data,res)
            res["gpoz"]=res["gpoz"]+1
        res["result"]=True
    else:    
        res["result"]=False        
 except IndexError:
    res["result"]=False
 return res

# находим опции в пакете
def FindOptions(data,res):
    #Тип запроса
    if data[res["gpoz"]]==53: 
        res["option53"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]
        if data[res["gpoz"]+2]==1: res["op"]="DHCPDISCOVER"
        if data[res["gpoz"]+2]==3: res["op"]="DHCPREQUEST"
        if data[res["gpoz"]+2]==2: res["op"]="DHCPOFFER"
        if data[res["gpoz"]+2]==4: res["op"]="DHCPOFFER"
        if data[res["gpoz"]+2]==5: res["op"]="DHCPACK"
        res["gpoz"]=res["gpoz"]+ln+1;
        return res
    #MAC address клиента
    if data[res["gpoz"]]==61:                 
        res["option61"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]
        htype=data[res["gpoz"]+2]
        res["HType"]="unknown";
        if htype==1:res["HType"]="Ethernet";        
        res["ClientMacAddress"]=data[res["gpoz"]+3:res["gpoz"]+2+ln].hex()
        res["ClientMacAddressByte"]=data[res["gpoz"]+3:res["gpoz"]+2+ln]
        res["gpoz"]=res["gpoz"]+ln+1;
        return res
    #DHCP Auto
    if data[res["gpoz"]]==116:                 
        res["option116"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]
        res["DHCPAUTO"]=True;
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    #HostName - имя железки
    if data[res["gpoz"]]==12:                 
        res["option12"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]
        res["HostName"]=data[res["gpoz"]+2:res["gpoz"]+ln+2]
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    #Vendor - производитель
    if data[res["gpoz"]]==60:                 
        res["option60"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]
        res["Vendor"]=data[res["gpoz"]+2:res["gpoz"]+ln+2]
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    #Request List - список чего запрашивает железка
    if data[res["gpoz"]]==55:                 
        res["option55"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]
        preq=0;
        while preq<ln:
            if data[res["gpoz"]+2+preq]==1:res["ReqListSubnetMask"]=True;
            if data[res["gpoz"]+2+preq]==15:res["ReqListDomainName"]=True;
            if data[res["gpoz"]+2+preq]==3:res["ReqListRouter"]=True;
            if data[res["gpoz"]+2+preq]==6:res["ReqListDNS"]=True;
            if data[res["gpoz"]+2+preq]==31:res["ReqListPerfowmRouterDiscover"]=True;
            if data[res["gpoz"]+2+preq]==33:res["ReqListStaticRoute"]=True;
            if data[res["gpoz"]+2+preq]==43:res["ReqListVendorSpecInfo"]=43;
            preq=preq+1        
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # Запрошенный IP адрес
    if data[res["gpoz"]]==50:                 
        res["option50"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["RequestedIpAddress"]=socket.inet_ntoa(pack('BBBB',data[res["gpoz"]+2],data[res["gpoz"]+3],data[res["gpoz"]+4],data[res["gpoz"]+5]));    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # IP DHCP сервера
    if data[res["gpoz"]]==54:                 
        res["option54"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["DHCPServerIP"]=socket.inet_ntoa(pack('BBBB',data[res["gpoz"]+2],data[res["gpoz"]+3],data[res["gpoz"]+4],data[res["gpoz"]+5]));    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # IP Lease Time
    if data[res["gpoz"]]==51:                 
        res["option51"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["DHCPLeaseTime"]=data[res["gpoz"]+2]*256*256*256*256+data[res["gpoz"]+3]*256*256+data[res["gpoz"]+4]*256+data[res["gpoz"]+5];    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # Subnet Mask
    if data[res["gpoz"]]==1:                 
        res["option1"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["SubnetMask"]=socket.inet_ntoa(pack('BBBB',data[res["gpoz"]+2],data[res["gpoz"]+3],data[res["gpoz"]+4],data[res["gpoz"]+5]));    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # Router
    if data[res["gpoz"]]==3:                 
        res["option3"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["Router"]=socket.inet_ntoa(pack('BBBB',data[res["gpoz"]+2],data[res["gpoz"]+3],data[res["gpoz"]+4],data[res["gpoz"]+5]));    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # DNS
    if data[res["gpoz"]]==6:                 
        res["option6"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["DNS"]=socket.inet_ntoa(pack('BBBB',data[res["gpoz"]+2],data[res["gpoz"]+3],data[res["gpoz"]+4],data[res["gpoz"]+5]));    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    # NTPS сервер времени
    if data[res["gpoz"]]==42:                 
        res["option42"]=data[res["gpoz"]];
        ln=data[res["gpoz"]+1]        
        res["NTPS"]=socket.inet_ntoa(pack('BBBB',data[res["gpoz"]+2],data[res["gpoz"]+3],data[res["gpoz"]+4],data[res["gpoz"]+5]));    
        res["gpoz"]=res["gpoz"]+ln+1;                          
        return res
    
    return res

def padding0(cnt):
    res=b''
    pz=0
    while pz<cnt:        
        res=res+pack("B",0)
        pz=pz+1
    return res    
# Собираем предложение DHCPOFFER
def CreateDHCPOFFER(packet):
    print("---собираемся отвечать..")
    res=pack("B",2)     # тип ответа 
    res=res+pack("B",1) # тип железа Ethernet
    res=res+pack("B",6) # длина мас адреса
    res=res+pack("B",0) # количество шагов
    res=res+pack("BBBB",packet["xidbyte"][0],packet["xidbyte"][1],packet["xidbyte"][2],packet["xidbyte"][3]) # идентификатор посылки
    res=res+pack("BB",0,0) # сколько времени прошло?
    res=res+pack("BB",0,0) # флаги
    res=res+pack("BBBB",0,0,0,0) # кому отсылаем (всем)
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.19") # какой IP предлагает
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.71") # какой IP у DHCP сервера
    res=res+socket.inet_pton(socket.AF_INET, "0.0.0.0") # какой Relay
    res=res+pack("BBBBBB",packet["ClientMacAddressByte"][0],packet["ClientMacAddressByte"][1],packet["ClientMacAddressByte"][2],packet["ClientMacAddressByte"][3],packet["ClientMacAddressByte"][4],packet["ClientMacAddressByte"][5]) # MAC получателя
    res=res+padding0(202);
    res=res+packet["magic_cookie"]; # магическое число
    res=res+pack("BBB",53,1,2) # 53 опция, обозначем, что это пакет OFFER (предложение)
    res=res+pack("BB",54,4) # 54 опция, кто дает адрес?
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.71")
    res=res+pack("BBBBBB",51,4,0,0,1,255) # 51 опция, время жизни адреса
    res=res+pack("BB",1,4) # 1 опция Mask
    res=res+socket.inet_pton(socket.AF_INET, "255.255.255.0")
    res=res+pack("BB",3,4) # 1 опция Router
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.1")
    res=res+pack("BB",6,4) # 6 опция DNS
    res=res+socket.inet_pton(socket.AF_INET, "8.8.8.8")
    res=res+pack("B",255) # END
    res=res+padding0(28);
    #print ("LEN:",len(res));
    return res
def CreateDHCPACK(packet):
    print("---собираемся отвечать..")
    res=pack("B",2)     # тип ответа 
    res=res+pack("B",1) # тип железа Ethernet
    res=res+pack("B",6) # длина мас адреса
    res=res+pack("B",0) # количество шагов
    res=res+pack("BBBB",packet["xidbyte"][0],packet["xidbyte"][1],packet["xidbyte"][2],packet["xidbyte"][3]) # идентификатор посылки
    res=res+pack("BB",0,0) # сколько времени прошло?
    res=res+pack("BB",0,0) # флаги
    res=res+pack("BBBB",0,0,0,0) # кому отсылаем (всем)
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.19") # какой IP предлагает
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.71") # какой IP у DHCP сервера
    res=res+socket.inet_pton(socket.AF_INET, "0.0.0.0") # какой Relay
    res=res+pack("BBBBBB",packet["ClientMacAddressByte"][0],packet["ClientMacAddressByte"][1],packet["ClientMacAddressByte"][2],packet["ClientMacAddressByte"][3],packet["ClientMacAddressByte"][4],packet["ClientMacAddressByte"][5]) # MAC получателя
    res=res+padding0(202);
    res=res+packet["magic_cookie"]; # магическое число
    res=res+pack("BBB",53,1,5) # 53 опция, обозначем, что это пакет ACK (подтверждение)
    res=res+pack("BB",54,4) # 54 опция, кто дает адрес?
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.71")
    res=res+pack("BBBBBB",51,4,0,0,1,255) # 51 опция, время жизни адреса
    res=res+pack("BB",1,4) # 1 опция Mask
    res=res+socket.inet_pton(socket.AF_INET, "255.255.255.0")
    res=res+pack("BB",3,4) # 1 опция Router
    res=res+socket.inet_pton(socket.AF_INET, "192.168.0.1")
    res=res+pack("BB",6,4) # 6 опция DNS
    res=res+socket.inet_pton(socket.AF_INET, "8.8.8.8")
    res=res+pack("B",255) # END
    res=res+padding0(28);
    #print ("LEN:",len(res));
    return res

 

Многопоточный опрос уровней абонентов станций GPON OLT

На выходе скрипт обновляет таблицу в MySQL, уровнем сигнала:

#!/usr/local/bin/python
# coding=utf-8

import mysql.connector
from mysql.connector import Error
import config    
import func
import socket
import re
from tendo import singleton
from pysnmp.hlapi import *
import threading
import time 


vr="1.0"
info="Сей дивный скрипт лезет snmp запросом на свичи olt/pon и опрашивает уровни"
copyleft="(с) 2018 by Pavel Gribov, http://грибовы.рф";
#выводим имя ПК и версию скрипта                
hostname = socket.gethostname()
print "Server: ",hostname
print "Version: ",vr
print "info: ",info
print "Copyright: ",copyleft

workcount=50; #количество потоков для опроса


def GetArrayLevels(ip,comm,oid):
 res=None
 errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(SnmpEngine(),
           CommunityData(comm),
           UdpTransportTarget(
               (ip, 161), timeout=2.0, retries=0
           ),
           ContextData(),
           ObjectType(ObjectIdentity(oid)))
 )  	     
 if errorIndication:
    print("Ошибка:",ip,comm,oid,errorIndication)
    return res
 elif errorStatus:
    print('%s at %s' % (errorStatus.prettyPrint(),
                        errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
    return res			
 else:
    for varBind in varBinds:     
     if varBind[1]<0: res=varBind[1]
 return res

def worker(ip,community,ind,idr): 
    rz=GetArrayLevels(ip,community,".1.3.6.1.4.1.3320.101.10.5.1.5."+str(ind))
    try:
        conn2 = mysql.connector.connect(host=config.noc_host,database=config.noc_base,user=config.noc_user,password=config.noc_pass)
        #if conn2.is_connected(): func.putlog('--cоединение с БД '+config.noc_base+' установлено')
    except Error as e:
        print("Ошибка: ",e);
        exit(0);    
    finally:
        if rz!=None: 
                print ("Level:",rz);
                sql="update oltlevels set level=%s,lastmod=now() where id=%s";
                print ("update oltlevels set level="+str(rz)+" where id="+str(idr))
                ccr = conn2.cursor(dictionary=True,buffered=True)
                ccr.execute(sql,[str(rz),idr]);  
                conn2.commit();
    conn2=None
func.putlog("-скрипт стартовал");
func.putlog("--проверяю, а не запущены ли мы уже?");
try:
 me = singleton.SingleInstance() 
except:
    func.putlog("--мы уже запущены!");    
    exit(1)
func.putlog("--Ок. Одна копия, работаем дальше");    
func.putlog("--соединяемся с noc");
try:
    conn = mysql.connector.connect(host=config.noc_host,database=config.noc_base,user=config.noc_user,password=config.noc_pass)
    if conn.is_connected(): func.putlog('--cоединение с БД '+config.noc_base+' установлено')
except Error as e:
    print("Ошибка: ",e);
    exit(0);    
finally:
    func.putlog("---делаем выборку устройств для опроса");
    sql="select * from oltlevels order by rand()";
    cursor = conn.cursor(dictionary=True,buffered=True)
    cursor.execute(sql);
    row = cursor.fetchone()	    
    while row is not None:      
        ip=row["ip"]
        community=row["community"]
        idr=row["id"]
        ind=row["ind"]
        func.putlog("----опрашиваем "+str(ip)+" ind="+str(ind)+",id="+str(idr));                
        thread = threading.Thread(target=worker, args=(ip,community,ind,idr,)).start()	
        while threading.active_count() >workcount:
         time.sleep(1)

        row = cursor.fetchone()	 
        
    while threading.active_count() >workcount:
         time.sleep(1)    
    func.putlog("---закончили");