思路:
python netsnmp模块采集交换机SNMP信息,通过pyzabbix 连接Zabbix API 自动生成带有端口描述信息的graph
测试环境 python2.7
软件包:
net-snmp-5.4.4.tar.gz
pyzabbix
net-snmp编译参数
cd net-snmp-5.4.4 ./configure --with-python-modules --prefix=/usr/local/net-snmp --enable-developer-enable-shared make && make install cd python python2.7 setup.py install
安装pyzabbix
pip install pyzabbix
Zabbix API item.create 好像不支持创建以SNMP的方法来创建的,所以这边以以low level discovery方法来采集交换机的端口, 这边事先手动创建以low level discove
#!/usr/bin/env python2.7 import netsnmp import os from pyzabbix import ZabbixAPI import re import sys #import itertools class SnmpSession(object): def __init__(self,oid='ifDescr',Version=2,DestHost='lcoalhost',Community=''): a,b=os.popen4('snmpwalk -v 2c -c %s %s %s' % (Community,DestHost,oid)) oid_value=[] for x in b: # print x.split('.')[1].split(' ')[0] oid_value.append(x.split('.')[1].split(' ')[0]) # print oid_value ifDescr=[] ifAlias=[] ifHCInOctets=[] ifHCOutOctets=[] for x in oid_value: ifDescr.append('ifDescr.%s' % x) ifAlias.append('ifAlias.%s' % x) ifHCInOctets.append('ifHCInOctets.%s' % x) ifHCOutOctets.append('ifHCOutOctets.%s' % x) # print ifDescr # print ifAlias # print ifHCInOctets # print ifHCOutOctets if oid == 'ifDescr': self.oids=ifDescr if oid == 'ifAlias': self.oids=ifAlias if oid == 'ifHCInOctets': slef.oids='ifHCInOctets' if oid == 'ifHCOutOctets': self.oids=ifHCOutOctets # print self.oids self.oid=oid self.Version=Version self.DestHost=DestHost self.Community=Community def query(self): try: result=netsnmp.snmpwalk(self.oid,Version=self.Version,DestHost=self.DestHost,Community=self.Community) ifDescr_d={} for x in zip(self.oids,list(result)): ifDescr_d[x[0]]=x[1] # print ifDescr_d if len(ifDescr_d) == 0: sys.exit(2) return ifDescr_d except: print 'switch Oid or ip is problem' sys.exit(3) #print sys.exc_info() # print result class zabbix(object): #主模块会调用上面的类 def __init__(self,hostname,Community,swich_ip,columns,name,graph,screen): self.server = 'http://10.0.100.12/zabbix' #Zabbix的服务器IP self.user = 'admin' #Zabbix的帐号 self.passwd = 'admin' #Zabbix的密码 # self.ip = ip # self.host = host self.hostname = hostname # self.oid = oid self.Community = Community self.swich_ip = swich_ip self.columns = columns self.dynamic = 0 self.name = name self.graph = graph self.screen = screen def __login(self): #登录Zabbix API的方法后面会多次被调用 zapi = ZabbixAPI(self.server) zapi.login(self.user,self.passwd) return zapi def __get_host(self): #获取主机的方法 list_host=self.__login().host.get(output='extend',filter={'host':self.hostname,}) #print list_host return list_host[0]['hostid'] def __get_item(self): #获取项目的方法 list_item=self.__login().item.get(output='extend',hostids=self.__get_host()) itemids={} for x in list_item: # print x['name'],x['itemid'] itemids[(x['name'])]=x['itemid'] # break # print itemids return itemids def __graph_create(self): #创建绘图的方法 items=self.__get_item() #print items desc=SnmpSession(oid='ifDescr',DestHost=self.swich_ip,Community=self.Community).query() #被调用的类 alias=SnmpSession(oid='ifAlias',DestHost=self.swich_ip,Community=self.Community).query() # print alias.values() port_desc={} desc_1={} for x in desc.keys(): desc_1[x.split('.')[1]]=desc[x] alias_1={} for x in alias.keys(): alias_1[x.split('.')[1]]=alias[x] for x in desc_1.keys(): port_desc[desc_1[x]]=alias_1[x] # print port_desc group_items={} for x in desc.values(): # print x aa=[] for y in items.keys(): # print y if re.search(x+'$',y): aa.append(items[y]) group_items[x]=aa # print group_items desc_and_port={} for x in port_desc.keys(): # print x for y in group_items.keys(): # print y if re.search(x+'$',y): # print y,port_desc[x],group_items[y] desc_and_port['%s (%s)' % ( y,port_desc[x] )]=group_items[y] # break # self.__login().graph.create( # print desc_and_port def b(x): return int(re.split('^\D+',x)[1].split(' ')[0].split('/')[-1]) #for x in desc_and_port.keys(): print sorted(desc_and_port,key=b) for x in sorted(desc_and_port,key=b): self.__login().graph.create(gitems=[{ "itemid":desc_and_port[x][0], #这边可以修改绘图的参数 "drawtype":"0", "sortorder":"0", "color":"0000CC", "yaxisside":"0", "calc_fnc":"2", "type":"0", "periods_cnt":"5" }, { "itemid":desc_and_port[x][1], "drawtype":"0", "sortorder":"1", "color":"00CC00", "yaxisside":"0", "calc_fnc":"2", "type":"0", "periods_cnt":"5" }], name=x, width="900", height="200", yaxismin="0.0000", yaxismax="3.0000", # templateid="0", show_work_period="1", show_triggers="1", graphtype="0", show_legend="1", show_3d="0", percent_left="0.0000", percent_right="0.0000", ymin_type="0", ymax_type="0", ymin_itemid="0", ymax_itemid="0") def __get_graph(self): #获取你需要的绘图 在下面生成screen需要 graphs=[] list_graph=self.__login().graph.get(output='extend',hostids=self. __get_host()) for x in list_graph: # print x['graphid'] if not re.search('Vlanif',x['name'].split(' ')[0]): if not re.search('LoopBack',x['name'].split(' ')[0]): if not re.search('NULL',x['name'].split(' ')[0]): if not re.search('Ethernet0/0/0',x['name'].split(' ')[0]): if not re.search('Console',x['name'].split(' ')[0]): print x['name'].split(' ')[0],x['graphid'] graphs.append(x['graphid']) graph_list=[] x = 0 y = 0 for graph in sorted(graphs): # print "x is " + str(x) # print "y is " + str(y) graph_list.append({ "resourcetype":'0', #这边可以修改screen的参数 "resourceid": graph, "width": "500", "height": "100", "x": str(x), "y": str(y), "colspan": "0", "rowspan": "0", "elements": "0", "valign": "0", "halign": "0", "style": "0", "url": "", "dynamic": str(self.dynamic) }) x += 1 # print type(x) # print type(self.columns) if x == int(self.columns): x = 0 y += 1 #print graph_list return graph_list def __create_screen(self): #创建screen的方法 graphids=self.__get_graph() columns = int(self.columns) if len(graphids) % self.columns == 0: vsize = len(graphids) / self.columns else: vsize = (len(graphids) / self.columns) + 1 # print graphids self.__login().screen.create(name=self.name,hsize=self.columns,vsize=vsize,screenitems=graphids) def __exists_screen(self): #判断 list_exists=self.__login().screen.exists(name=self.name) if list_exists: print '%s is exists' % self.name sys.exit(1) def __exists_host(self): #判断 list_exists=self.__login().host.exists(host=self.hostname) if not list_exists: print "%s is not exists" % self.hostname sys.exit(1) #return graphs # # def __del_graph(self): # a=self.__get_graph() # self.__login().graph.delete(a) def main(self): self.__exists_host() self.__exists_screen() # self.__get_host() # self.__get_item() if self.graph: self.__graph_create() # self.__get_graph() # self.__del_graph() if self.screen: self.__create_screen() if __name__ == '__main__': from optparse import OptionParser parser = OptionParser() parser.add_option('-G', dest='graphname', help='Zabbix Host create new screen ') parser.add_option('-H', dest='hostname', help='Zabbix Host to create screen from') parser.add_option('-c', dest='columns', type=int, help='number of columns in the screen') parser.add_option('-C', dest='Community', help='switch SNMP community') parser.add_option('-s', dest='switch', help='switch ip') parser.add_option('-x', dest='execute',action='store_true',default=False, help='create host graph') parser.add_option('-n',dest='screen',action='store_true',default=False, help='whether create zabbix screen') options,args=parser.parse_args() a=zabbix(hostname=options.hostname,Community=options.Community,swich_ip=options.switch,columns=options.columns,name=options.graphname,graph=options.execute,screen=options.screen) a.main() #对于多块板卡的生成的screen有点问题 后期会补上
-G 生成新的screen
-H 自己定义的主机名
-c 需要生成的列
-s 交换的ip地址, (这边交换的ip地址可能会跟你的 Host name 不同)
-x 是否开启创建graph的功能
-n 是否开启screen 功能
注意 -C -s 如果没有填正确的信息 脚本会报错,这个后续改下
例子: ./switch_desc_port_and_create_screen.py -G tom -H 10.0.10.100 -c 2 -C tom -s 10.0.10.100 -x True -n True
Graph出来啦
Screen 也出来了
这边出来的是你刚才low level discovery 定义的
现在你可以改name了
这边也就改变了
如果脚本有问问题请向我指出谢谢!