思路:        

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

wKioL1NObQDQyY4wAAC_U2hqLwo568.jpg


wKioL1NObWjAXRhsAAFavlmtkrI002.jpg

wKiom1NObt3RNKuGAAJuVLc4QE0336.jpg

wKioL1NOcRDi39KmAAOQoAxhRFI081.jpg


wKiom1NOcXXxE57xAAMOiT6KVm8401.jpg



#!/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有点问题 后期会补上

wKioL1NOdZny-TucAAFit0XRoig699.jpg

-G 生成新的screen

-H  自己定义的主机名

wKioL1NOdpWiw74yAADQWHN-1Es425.jpg

-c  需要生成的列

wKiom1NOdw7CpLI_AACeGKXmR9s899.jpg

-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



wKioL1NOd3fAAbBYAAVwVLKmI20699.jpg

Graph出来啦



wKioL1NOd9_ThOEqAAAUoCa-WgA760.jpg

Screen 也出来了



wKiom1NOeE2hVwhVAAE79_Gr064142.jpg

这边出来的是你刚才low level discovery 定义的


wKiom1NOeKbRsxjpAACLnbJAi24783.jpg


现在你可以改name


wKioL1NOeKvSUwxMAAEFHPvBK7Q147.jpg


wKiom1NOeRWAs27DAAFBJmSw0dE006.jpg

这边也就改变了

如果脚本有问问题请向我指出谢谢!