def get_inventory(self): from netsnmp import VarList, Varbind, Session result = [] try: outletobjs = VarList(Varbind('.1.3.6.1.4.1.10418.17.2.5.5.1.4')) stateobjs = VarList(Varbind('.1.3.6.1.4.1.10418.17.2.5.5.1.5')) slotobjs = VarList(Varbind('.1.3.6.1.4.1.10418.17.2.5.3.1.3')) session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.walk(outletobjs) session.walk(stateobjs) session.walk(slotobjs) slotdict = dict(map(lambda var: (var.iid, var.val), slotobjs)) for indx, outlet in enumerate(outletobjs, 0): result.append({ 'slot': outlet.tag[34:], 'unit': outlet.iid, 'name': outlet.val, 'state': Device.get_outlet_state(stateobjs[indx].val), 'slotname': slotdict.get(outlet.tag[34:], "unknown") }) except Exception as exception_error: self.log_msg("Avocent : error loading conf " + str(exception_error)) return result
def get_count_port_errors(self, port, curr): """ Количество ошибок на порту """ oid_errors = 'iso.3.6.1.2.1.2.2.1.' counts = (14, 20) if_index = self.get_snmp_port_number(port) if not if_index or if_index < 0: return dumps({ 'status' : Status.ERROR }) # формируем запрос со всеми оидами oids = VarList() for index in counts: oid = Varbind('{0}{1}.{2}'.format(oid_errors, index, if_index)) oids.append(oid) # лист с количеством ошибок на каждом счетчике res = self.sess.get(oids) # суммируем ошибки errors = 0 for count in res: errors += int(count) delta = 0 if curr > 0: delta = errors - int(curr) return dumps({ 'status' : Status.SUCCESS, 'errors' : errors, 'delta' : delta })
def get_vm_list(self, aSort=None): # aSort = 'id' or 'name' from netsnmp import VarList, Varbind, Session statelist = [] try: vmnameobjs = VarList(Varbind('.1.3.6.1.4.1.6876.2.1.1.2')) vmstateobjs = VarList(Varbind('.1.3.6.1.4.1.6876.2.1.1.6')) session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.walk(vmnameobjs) session.walk(vmstateobjs) for indx, result in enumerate(vmnameobjs): statetuple = { 'id': result.iid, 'name': result.val, 'state': vmstateobjs[indx].val, 'state_id': Device.get_state_str(vmstateobjs[indx].val) } statelist.append(statetuple) except: pass if aSort: statelist.sort(key=lambda x: x[aSort]) return statelist
def cable_test(self, port): """ Кабельная диагностика """ oid_diag = 'iso.3.6.1.4.1.2011.5.25.31.1.1.7.1.' port = self.get_snmp_port_number(port) if not port or port < 0: return dumps({ 'status' : Status.ERROR }) count = 10 for c in xrange(count): oids = VarList() # 2 - status, 3 - length for index in 2, 3: oid_str = '{0}{1}.{2}'.format(oid_diag, index, port) oid = Varbind(oid_str) oids.append(oid) res = self.sess.get(oids) if not res: msg = 'not status answer {0}:{1}'.format(self.ip, port) print(msg) return dumps({ 'status' : Status.ERROR, 'msg' : msg }) if res[1] not in ('150', '204'): break elif c + 1 == count: return dumps({ 'status' : Status.CBNOINFO }) data = {} status = int(res[0]) - 1 p1, col1 = Switch.convert_descr(str(status)) len1 = int(res[1]) data['p1col'] = col1 data['p1st'] = p1 data['p1len'] = len1 return dumps({ 'status': Status.SUCCESS, 'data' : data })
def detect(self): ret = {} from zdcp.SettingsContainer import SC from netsnmp import VarList, Varbind, Session try: # .1.3.6.1.2.1.1.1.0 : Device info # .1.3.6.1.2.1.1.5.0 : Device name devobjs = VarList(Varbind('.1.3.6.1.2.1.1.1.0'), Varbind('.1.3.6.1.2.1.1.5.0')) session = Session(Version = 2, DestHost = self._ip, Community = SC['snmp']['read_community'], UseNumeric = 1, Timeout = 100000, Retries = 2) session.get(devobjs) ret['result'] = "OK" if (session.ErrorInd == 0) else "NOT_OK" except Exception as err: ret['snmp'] = "Not able to do SNMP lookup (check snmp -> read_community): %s"%str(err) else: ret['info'] = {'model':'unknown', 'type':'generic','snmp':devobjs[1].val.lower() if devobjs[1].val else 'unknown'} if devobjs[0].val: infolist = devobjs[0].val.split() if infolist[0] == "Juniper": if infolist[1] == "Networks,": ret['info']['model'] = infolist[3].lower() for tp in [ 'ex', 'srx', 'qfx', 'mx', 'wlc' ]: if tp in ret['info']['model']: ret['info']['type'] = tp break else: subinfolist = infolist[1].split(",") ret['info']['model'] = subinfolist[2] elif infolist[0] == "VMware": ret['info']['model'] = "esxi" ret['info']['type'] = "esxi" elif infolist[0] == "Linux": ret['info']['model'] = 'debian' if "Debian" in devobjs[0].val else 'generic' else: ret['info']['model'] = " ".join(infolist[0:4]) return ret
def interfaces(self): from sdcp.SettingsContainer import SC from netsnmp import VarList, Varbind, Session interfaces = {} try: objs = VarList(Varbind('.1.3.6.1.2.1.2.2.1.2'), Varbind('.1.3.6.1.2.1.31.1.1.1.18')) session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.walk(objs) for entry in objs: intf = interfaces.get(int(entry.iid), { 'name': "None", 'description': "None" }) if entry.tag == '.1.3.6.1.2.1.2.2.1.2': intf['name'] = entry.val if entry.tag == '.1.3.6.1.2.1.31.1.1.1.18': intf[ 'description'] = entry.val if entry.val != "" else "None" interfaces[int(entry.iid)] = intf except Exception as exception_error: self.log_msg("Generic : error traversing interfaces: " + str(exception_error)) return interfaces
def get_vm_state(self, aid): from netsnmp import VarList, Varbind, Session try: vmstateobj = VarList(Varbind(".1.3.6.1.4.1.6876.2.1.1.6." + str(aid))) session = Session(Version = 2, DestHost = self._ip, Community = SC['snmp']['read_community'], UseNumeric = 1, Timeout = 100000, Retries = 2) session.get(vmstateobj) return vmstateobj[0].val except: pass return "unknown"
def get(self, oid): vb = Varbind(oid) vl = VarList(vb) try: val = self.session.get(vl)[0] except Exception: logging.warning("get failed on: {0} {1} ({2})".format( self.host, oid, self.session.ErrorStr)) return None return val
def get_vm_id(self, aname): from netsnmp import VarList, Varbind, Session try: vmnameobjs = VarList(Varbind('.1.3.6.1.4.1.6876.2.1.1.2')) session = Session(Version = 2, DestHost = self._ip, Community = SC['snmp']['read_community'], UseNumeric = 1, Timeout = 100000, Retries = 2) session.walk(vmnameobjs) for result in vmnameobjs: if result.val == aname: return int(result.iid) except: pass return -1
def get_count_port_errors(self, port, curr): """ Считывает по snmp количество ошибок на порту клиента Принимает массив с айпи свитча (ip), снмп-портом (port) и текущим количеством ошибок (cur) Возвращает количество ошибок и дельту, если в запросе было указано количество ошибок уже Huawei CX200 не поддерживается, поэтому сразу возвращает что это CX200 """ # http://support.huawei.com/enterprise/docinforeader.action?contentId=DOC1000027252&idPath=7919710|9856733|7923144|16561 (01-41 HUAWEI-IF-EXT-MIB) oid_errors = 'iso.3.6.1.4.1.2011.5.25.41.1.6.1.1.' # http://support.huawei.com/enterprise/docinforeader.action?contentId=DOC1000027252&idPath=7919710|9856733|7923144|16561 (01-41 HUAWEI-IF-EXT-MIB) counts = (11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33) if_index = self.get_snmp_port_number(port) if not if_index or if_index < 0: return dumps({ 'status' : Status.ERROR }) # формируем запрос со всеми оидами oids = VarList() for index in counts: oid = Varbind('{0}{1}.{2}'.format(oid_errors, index, if_index)) oids.append(oid) # лист с количеством ошибок на каждом счетчике res = self.sess.get(oids) # суммируем ошибки errors = 0 for count in res: errors += int(count) delta = 0 if curr > 0: delta = errors - int(curr) return dumps({ 'status' : Status.SUCCESS, 'errors' : errors, 'delta' : delta })
def get_count_port_errors(self, port, curr): """ Считывает по snmp количество ошибок на порту клиента Принимает массив с айпи свитча (ip), снмп-портом (port) и текущим количеством ошибок (cur) Возвращает количество ошибок и дельту, если в запросе было указано количество ошибок уже """ # dlink stored info about ports oid_errors = 'iso.3.6.1.2.1.2.2.1.' counts = (14, 20) # Может быть не надо, но запрос быстрый, так что оставим if_index = self.get_snmp_port_number(port) if not if_index or if_index < 0: return dumps({ 'status' : Status.ERROR }) # формируем запрос со всеми оидами oids = VarList() for index in counts: oid = Varbind('{0}{1}.{2}'.format(oid_errors, index, if_index)) oids.append(oid) # лист с количеством ошибок на каждом счетчике res = self.sess.get(oids) # суммируем ошибки errors = 0 for count in res: errors += int(count) delta = 0 if curr > 0: delta = errors - int(curr) return dumps({ 'status' : Status.SUCCESS, 'errors' : errors, 'delta' : delta })
def walk(self, oid, stripoid=True, expect_str=False): vb = Varbind(oid) vl = VarList(vb) self.session.walk(vl) ret = {} for v in vl: if v.tag is None: continue full_oid = v.tag (full_oid, val) = handle_vb(v, expect_str) if stripoid: full_oid = full_oid.replace(oid + ".", '') ret[full_oid] = val return ret
def switch_table(self): from socket import gethostbyaddr try: # Length of below is used to offset ip address (32) + 1 and mac base (33) + 1 cssidobjs = VarList(Varbind(".1.3.6.1.4.1.14525.4.4.1.1.1.1.15")) cipobjs = VarList(Varbind(".1.3.6.1.4.1.14525.4.4.1.1.1.1.4")) from sdcp.SettingsContainer import SC session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.walk(cssidobjs) session.walk(cipobjs) except: return ipdict = dict(map(lambda res: (res.tag[33:], res.val), cipobjs)) ret = [] for res in cssidobjs: macbase = res.tag[34:] mac = (macbase + "." + res.iid).split(".") mac = ":".join(map(lambda x: hex(int(x))[2:], mac)) try: clientname = gethostbyaddr(ipdict[macbase])[0] except: clientname = "unknown" ret.append({ 'Name': clientname, 'IP': ipdict.get(macbase), 'MAC': mac, 'SSID': res.val }) return ret
def detect(aDict): """Function docstring for detect TBD. TODO -> make this a function of generic device instead !!! ZEB Args: - ip (required) Output: """ from os import system if system("ping -c 1 -w 1 {} > /dev/null 2>&1".format(aDict['ip'])) != 0: return {'result':'NOT_OK', 'info':'Not pingable' } ret = {'result':'OK'} from netsnmp import VarList, Varbind, Session try: # .1.3.6.1.2.1.1.1.0 : Device info # .1.3.6.1.2.1.1.5.0 : Device name devobjs = VarList(Varbind('.1.3.6.1.2.1.1.1.0'), Varbind('.1.3.6.1.2.1.1.5.0')) session = Session(Version = 2, DestHost = aDict['ip'], Community = SC['snmp']['read_community'], UseNumeric = 1, Timeout = 100000, Retries = 2) session.get(devobjs) except Exception as err: ret['snmp'] = "Not able to do SNMP lookup (check snmp -> read_community): %s"%str(err) ret['info'] = {'model':'unknown', 'type':'generic','snmp':devobjs[1].val.lower() if devobjs[1].val else 'unknown'} if devobjs[0].val: infolist = devobjs[0].val.split() if infolist[0] == "Juniper": if infolist[1] == "Networks,": ret['info']['model'] = infolist[3].lower() for tp in [ 'ex', 'srx', 'qfx', 'mx', 'wlc' ]: if tp in ret['info']['model']: ret['info']['type'] = tp break else: subinfolist = infolist[1].split(",") ret['info']['model'] = subinfolist[2] elif infolist[0] == "VMware": ret['info']['model'] = "esxi" ret['info']['type'] = "esxi" elif infolist[0] == "Linux": ret['info']['model'] = 'debian' if "Debian" in devobjs[0].val else 'generic' else: ret['info']['model'] = " ".join(infolist[0:4]) return ret
def get_slot_names(self): from netsnmp import VarList, Varbind, Session slots = [] try: slotobjs = VarList(Varbind('.1.3.6.1.4.1.10418.17.2.5.3.1.3')) session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.walk(slotobjs) for slot in slotobjs: slots.append([slot.iid, slot.val]) except Exception as exception_error: self.log_msg("Avocent : error loading pdu member names " + str(exception_error)) return slots
def bulkwalk(self, oid, stripoid=True, startidx=None, endidx=None, expect_str=False): ret = {} if oid[0] != ".": oid = "." + oid startindexpos = startidx runningtreename = oid stop = False while (runningtreename.startswith(oid) and stop is False): vrs = VarList(Varbind(runningtreename, startindexpos)) result = self.session.getbulk(0, self.max_rep, vrs) if self.session.ErrorInd: logging.warn("walk failed on: {0} ({1})".format( self.host, self.session.ErrorStr)) key = None if not result: logging.warn("got no result: %s %s", self.host, oid) break """ Print output from running getbulk""" for i in vrs: if endidx and int(i.iid) > int(endidx): stop = True break if not i.tag.startswith(oid): break (full_oid, val) = handle_vb(i, expect_str) key = full_oid.replace(oid + ".", "") if stripoid: ret[key] = val else: ret[full_oid] = val """ Set startindexpos for next getbulk """ if not vrs[-1].iid or not key or stop: break startindexpos = vrs[-1].iid """ Refresh runningtreename from last result""" runningtreename = vrs[-1].tag return ret
def set_name(self, slot, unit, name): from netsnmp import VarList, Varbind, Session try: name = name[:16] session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['write_community'], UseNumeric=1, Timeout=100000, Retries=2) setobj = VarList( Varbind("enterprises", "10418.17.2.5.5.1.4.1.{}.{}".format(slot, unit), name, "OPAQUE")) session.set(setobj) return "{0}.{1}:'{2}'".format(slot, unit, name) except Exception as exception_error: self.log_msg("Avocent : error setting name " + str(exception_error)) return "Error setting name '%s'" % (name)
def get_state(self, slot, unit): from netsnmp import VarList, Varbind, Session try: stateobj = VarList( Varbind(".1.3.6.1.4.1.10418.17.2.5.5.1.5.1.{}.{}".format( slot, unit))) session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.get(stateobj) return { 'res': 'OK', 'state': Device.get_outlet_state(stateobj[0].val) } except Exception as e: self.log_msg("Avocent : error getting state:" + str(e)) return {'res': 'NOT_OK', 'info': str(e), 'state': 'unknown'}
def set_state(self, slot, unit, state): from netsnmp import VarList, Varbind, Session try: session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['write_community'], UseNumeric=1, Timeout=100000, Retries=2) setobj = VarList( Varbind("enterprises", "10418.17.2.5.5.1.6.1.{}.{}".format(slot, unit), Device.set_outlet_state(state), "INTEGER")) session.set(setobj) self.log_msg("Avocent : {0} set state to {1} on {2}.{3}".format( self._ip, state, slot, unit)) return {'res': 'OK'} except Exception as exception_error: self.log_msg("Avocent : error setting state " + str(exception_error)) return {'res': 'NOT_OK', 'info': str(exception_error)}
def get_inventory(self): from netsnmp import VarList, Varbind, Session from sdcp.SettingsContainer import SC result = [] try: portobjs = VarList(Varbind('.1.3.6.1.4.1.25049.17.2.1.2')) session = Session(Version=2, DestHost=self._ip, Community=SC['snmp']['read_community'], UseNumeric=1, Timeout=100000, Retries=2) session.walk(portobjs) for obj in portobjs: result.append({ 'interface': obj.iid, 'name': obj.val, 'port': str(6000 + int(obj.iid)) }) except Exception as exception_error: self.log_msg("OpenGear : error loading conf " + str(exception_error)) return result
def cable_test_all(self): """ Возвращает результат кабдиага на всех портах кроме активных и где активный договор """ # получим список всех 100мб портов oid_typeport = 'iso.3.6.1.2.1.2.2.1.3' oid_status = 'iso.3.6.1.2.1.2.2.1.8' var_types = self.sess.bulkwalk(oid_typeport) if not var_types: msg = 'Предположительно свитч лежит!' return dumps({ 'status' : Status.ERROR, 'msg' : msg }) var_status = self.sess.bulkwalk(oid_status) if not var_status: msg = 'Предположительно свитч лежит!' return dumps({ 'status' : Status.ERROR, 'msg' : msg }) if len(var_types) != len(var_status): print('len not equal on switch {0}'.format(self.ip)) return dumps({ 'status' : Status.ERROR }) t = {int(i.split('.')[-1]): int(y) for (i, j), (x, y) in zip(var_types, var_status) if int(j) == 6} data = {i + 1: k for i, (k, v) in enumerate(sorted(t.iteritems())) if v == 2} oid_dlink = 'iso.3.6.1.4.1.171.12.58.1.1.1.' rw_cabdiag = 12 oids = [] for port in data.values(): oid_str = '{0}{1}.{2}'.format(oid_dlink, rw_cabdiag, port) oid = Varbind(oid_str, '', 1, 'INTEGER') oids.append(oid) for oid in oids: self.sess.set(VarList(oid)) count = 0 status = '' sleep_time = 0.5 # ждем пока не вернет 3 (ready for test) завершения теста 6/sleep_time = 3sec oid = '{0}{1}'.format(oid_dlink, rw_cabdiag) while not status and not all(val == '3' for tag, val in status) and count < 6: status = self.sess.bulkwalk(oid) sleep(sleep_time) count += 1 for k, port in data.iteritems(): # 4-7 status pair 1-4, 8-11 length pair 1-4 oids = VarList() for index in 4, 5, 8, 9: oid = Varbind('{0}{1}.{2}'.format(oid_dlink, index, port)) oids.append(oid) res = self.sess.get(oids) # частный случай, длинк не может промерить кабель, так как он вставлен в активное оборудование if all(x == '0' for x in res): data[k] = { 'status' : Status.CBNOINFO } continue tmp = {} p1, col1 = Switch.convert_descr(res[0]) p2, col2 = Switch.convert_descr(res[1]) len1 = int(res[2]) len2 = int(res[3]) tmp['p1col'] = col1 tmp['p1st'] = p1 tmp['p1len'] = len1 tmp['p2col'] = col2 tmp['p2st'] = p2 tmp['p2len'] = len2 data[k] = { 'status': Status.SUCCESS, 'data' : tmp } return dumps({ 'status': Status.SUCCESS, 'data' : data })
def cable_test(self, port): oid_dlink = 'iso.3.6.1.4.1.171.12.58.1.1.1.' rw_cabdiag = 12 port = self.get_snmp_port_number(port) if not port or port < 0: return dumps({ 'status' : Status.ERROR }) oid_str = '{0}{1}.{2}'.format(oid_dlink, rw_cabdiag, port) oid = VarList(Varbind(oid_str, '', 1, 'INTEGER')) status = self.sess.set(oid) if not status: msg = 'not status answer {0}:{1}'.format(self.ip, port) print(msg) return dumps({ 'status' : Status.ERROR, 'msg' : msg }) count = 0 status = 2 sleep_time = 0.5 # ждем пока не вернет 3 (ready for test) завершения теста 6/sleep_time = 3sec oid = VarList(Varbind(oid_str)) while status != '3' and count < 6: status, = self.sess.get(oid) sleep(sleep_time) count += 1 # формируем запрос со всеми оидами oids = VarList() # 4-7 status pair 1-4, 8-11 length pair 1-4 for index in 4, 5, 8, 9: oid = Varbind('{0}{1}.{2}'.format(oid_dlink, index, port)) oids.append(oid) # лист с количеством ошибок на каждом счетчике res = self.sess.get(oids) # частный случай, длинк не может промерить кабель, так как он вставлен в активное оборудование if all(x == '0' for x in res): return dumps({ 'status' : Status.CBNOINFO }) data = {} p1, col1 = Switch.convert_descr(res[0]) p2, col2 = Switch.convert_descr(res[1]) len1 = int(res[2]) len2 = int(res[3]) data['p1col'] = col1 data['p1st'] = p1 data['p1len'] = len1 data['p2col'] = col2 data['p2st'] = p2 data['p2len'] = len2 return dumps({ 'status': Status.SUCCESS, 'data' : data })
def get_snmp_port_status(self, port): ''' Принимает айпи свитча и порт Возвращает его статус ''' if_index = self.get_snmp_port_number(port) # switch down by snmp if not if_index: stport = 'muted' stswitch = 'danger' # если свитч не ответил по снмп, попробуем пингануть r = self.__available_by_system_ping() if r: # свитч в апе, проблема в снмп коммунити stswitch = 'warning' return dumps({ 'isup' : 0, 'statusswitch' : stswitch, 'statusport' : stport, 'ip' : self.ip, 'port' : port }) # гиговый порт if if_index < 0: return dumps({ 'status' : Status.ERROR }) # список портов oid_ports = 'iso.3.6.1.2.1.2.2.1.' oids = VarList() # 7 - admin status, 8 - oper status, 5 - port speed http://www.opennet.ru/base/cisco/cisco_snmp.txt.html for index in 7, 8, 5: oid = Varbind('{0}{1}.{2}'.format(oid_ports, index, if_index)) oids.append(oid) # лист со статусом портов, административный и оперативный, 1 - up, 2 - down ret = self.sess.get(oids) admin = 0 if ret[0] == '2' else 1 oper = ret[1] speed = int(ret[2]) / 1000000 # None - error, 1 = port up, 2 = port down sw_status = 'success' port_status = 'muted' if not oper: port_status = 'muted' elif oper == '2': port_status = 'danger' elif oper == '1': if speed == 100: port_status = 'success' else: port_status = 'warning' return dumps({ 'isup' : 1, 'statusswitch' : sw_status, 'statusport' : port_status, 'statusadmin' : admin, 'ip' : self.ip, 'port' : port })