def test_sendTrap(self, mock_ntforg, mock_snmp_config): self.mock_queue = mock.MagicMock with mock.patch( 'bdssnmpadaptor.config.open', side_effect=[io.StringIO(self.CONFIG), io.StringIO(self.CONFIG), io.StringIO(self.CONFIG)]): ntf = snmp_notificator.SnmpNotificationOriginator( mock.MagicMock(config={}), self.mock_queue) self.my_loop.run_until_complete(ntf.sendTrap({})) mock_snmpEngine = mock_snmp_config.getSnmpEngine.return_value expectedVarBinds = [ (rfc1902.ObjectIdentifier('1.3.6.1.2.1.1.3.0'), mock.ANY), (rfc1902.ObjectIdentifier('1.3.6.1.6.3.1.1.4.1.0'), rfc1902.ObjectIdentifier('1.3.6.1.4.1.50058.103.1.0.1.1')), (rfc1902.ObjectIdentifier('1.3.6.1.4.1.50058.104.2.1.1.0'), rfc1902.Integer32(1)), (rfc1902.ObjectIdentifier('1.3.6.1.4.1.50058.104.2.1.2.0'), rfc1902.OctetString('error')), (rfc1902.ObjectIdentifier('1.3.6.1.4.1.50058.104.2.1.3.0'), rfc1902.Integer32(0)), (rfc1902.ObjectIdentifier('1.3.6.1.4.1.50058.104.2.1.4.0'), rfc1902.OctetString('error')), ] ntf._ntfOrg.sendVarBinds.assert_called_once_with( mock_snmpEngine, mock.ANY, None, '', expectedVarBinds, mock.ANY)
def _update_battery_oids(self, charge_level, old_level): """Update OIDs associated with UPS Battery Args: charge_level(int): new battery level (between 0 & 1000) """ # 100% oid_adv = self.get_oid_by_name("AdvBatteryCapacity") oid_hp = self.get_oid_by_name("HighPrecBatteryCapacity") oid_basic = self.get_oid_by_name("BasicBatteryStatus") if oid_adv: self._update_oid_value(oid_adv, snmp_data_types.Gauge32(charge_level / 10)) if oid_hp: self._update_oid_value(oid_hp, snmp_data_types.Gauge32(charge_level)) if not oid_basic: return if charge_level <= 100: low_bat_value = oid_basic.specs["batteryLow"] self._update_oid_value(oid_basic, snmp_data_types.Integer32(low_bat_value)) elif old_level <= 100 < charge_level: norm_bat_value = oid_basic.specs["batteryNormal"] self._update_oid_value(oid_basic, snmp_data_types.Integer32(norm_bat_value))
def __createVLAN(self, vlan_id, vlan_name): """\brief Creates a vlan given an id \param vlan_id (\c int) vlan id to add \return (\int) 0 if the operation is successful, -1 if it failed. """ log.debug(str(OID.dot1qVlanStaticRowStatus + (vlan_id, ))) # you create a vlan using its tagged id snmp_list = [] snmp_list.append((OID.dot1qVlanStaticName + (vlan_id, ), rfc1902.OctetString(str(vlan_name)))) snmp_list.append((OID.dot1qVlanStaticEgressPorts + (vlan_id, ), rfc1902.OctetString(self.getEmptyBitMap(64)))) snmp_list.append((OID.dot1qVlanForbiddenEgressPorts + (vlan_id, ), rfc1902.OctetString(self.getEmptyBitMap(64)))) snmp_list.append((OID.dot1qVlanStaticUntaggedPorts + (vlan_id, ), rfc1902.OctetString(self.getEmptyBitMap(64)))) snmp_list.append( (OID.dot1qVlanStaticRowStatus + (vlan_id, ), rfc1902.Integer32(4))) self.snmp.complex_set(snmp_list) if self.snmp.getErrorStatus(): log.debug("Error creating vlan with id " + str(vlan_id) + " on switch " + str(self.getSwitchName())) return -1 return 0
def __getSimpleMACTable(self): """\brief Gets the full learned mac table from the switch, returning a list of MACTableEntry objects. \return (\c list) A list of MACTableEntry objects with the results. """ portsTable = self.getDot1qTpFdbPort(True) learnedTypeTable = self.getDot1qTpFdbStatus(True) result = [] for learnedTypeTableRow in learnedTypeTable: for learnedname, learnedval in learnedTypeTableRow: if learnedval == rfc1902.Integer32('3'): learnedname = rfc1902.ObjectName( (learnedname.prettyPrint()).replace( OID.dot1qTpFdbStatus.prettyPrint(), OID.dot1qTpFdbPort.prettyPrint())) for portTableRow in portsTable: for portname, portval in portTableRow: if learnedname == portname: mac = ("%02x:%02x:%02x:%02x:%02x:%02x" % ( int(learnedname[14]), int(learnedname[15]), int(learnedname[16]), int(learnedname[17]), int(learnedname[18]), int( learnedname[19]))) mac = mac.replace("0x", "").upper() result.append((mac, str(portval))) return result
def addMacsToPorts(self): portsTable = self.getDot1qTpFdbPort(True) learnedTypeTable = self.getDot1qTpFdbStatus(True) self.resetPortsMacInfo() for learnedTypeTableRow in learnedTypeTable: for learnedname, learnedval in learnedTypeTableRow: if learnedval == rfc1902.Integer32('3'): learnedname = rfc1902.ObjectName( (learnedname.prettyPrint()).replace( OID.dot1qTpFdbStatus.prettyPrint(), OID.dot1qTpFdbPort.prettyPrint())) for portTableRow in portsTable: for portname, portval in portTableRow: if learnedname == portname: mac = ("%02x:%02x:%02x:%02x:%02x:%02x" % ( int(learnedname[14]), int(learnedname[15]), int(learnedname[16]), int(learnedname[17]), int(learnedname[18]), int( learnedname[19]))) mac = mac.replace("0x", "").upper() port = self.getPort(portval) mac_list = port.getMacs() mac_list.append(mac) port.setMacs(mac_list)
def getFullMACTable(self): """\brief Gets the full learned mac table from the switch, returning a list of MACTableEntry objects. \return (\c list) A list of MACTableEntry objects with the results. """ portsTable = self.snmp.walk(OID.dot1dTpFdbPort) learnedTypeTable = self.snmp.walk(OID.dot1dTpFdbStatus) result = [] for learnedTypeTableRow in learnedTypeTable: for learnedname, learnedval in learnedTypeTableRow: if learnedval == rfc1902.Integer32('3'): learnedname = rfc1902.ObjectName((learnedname.prettyPrint()).replace(OID.dot1dTpFdbStatus.prettyPrint(),OID.dot1dTpFdbPort.prettyPrint())) for portTableRow in portsTable: for portname, portval in portTableRow: if learnedname == portname: result.append(MACTableEntry(("%02x:%02x:%02x:%02x:%02x:%02x" % (int(learnedname[11]),int(learnedname[12]),int(learnedname[13]),int(learnedname[14]),int(learnedname[15]),int(learnedname[16]))).replace("0x","").upper(),portval,'3',self.__switchName)) return result for key in learnedTypeTable.keys(): if (learnedTypeTable[key] == str(3)): mac = MACTableEntry((macAddressesTable[key]).replace(' ',':',5).upper(),portsTable[key],learnedTypeTable[key]) mac.setSwitch(self.getSwitchID()) result.append(mac)
def __getFDBTable(self, result): portsTable = self.snmp.walk(OID.dot1dTpFdbPort) learnedTypeTable = self.snmp.walk(OID.dot1dTpFdbStatus) for learnedTypeTableRow in learnedTypeTable: for learnedname, learnedval in learnedTypeTableRow: if learnedval == rfc1902.Integer32('3'): learnedname = rfc1902.ObjectName( (learnedname.prettyPrint()).replace( OID.dot1dTpFdbStatus.prettyPrint(), OID.dot1dTpFdbPort.prettyPrint())) for portTableRow in portsTable: for portname, portval in portTableRow: if learnedname == portname: result.append( MACTableEntry( ("%02x:%02x:%02x:%02x:%02x:%02x" % (int(learnedname[11]), int(learnedname[12]), int(learnedname[13]), int(learnedname[14]), int(learnedname[15]), int(learnedname[16]))).replace( "0x", "").upper(), portval, '3', self.getSwitchName())) #return result return for key in learnedTypeTable.keys(): if (learnedTypeTable[key] == str(3)): mac = MACTableEntry( (macAddressesTable[key]).replace(' ', ':', 5).upper(), portsTable[key], learnedTypeTable[key]) mac.setSwitch(self.getSwitchID()) result.append(mac)
def __parsePortList(self, pl, tagged): raw_ports = array('B') for i in range(0, len(pl)): raw_ports.extend(unpack('B', pl[i])) mask = [128, 64, 32, 16, 8, 4, 2, 1, 0] port_number = 0 ports = [] port_ids = self.getPortIDs() port_names = self.getPortNames() for port in raw_ports: for slot in range(0, 8): port_number = port_number + 1 if (port & Switch.mask[slot] == Switch.mask[slot]): for port_id in port_ids: if (port_id[0][0][len(port_id[0][0]) - 1] == rfc1902.Integer32(port_number)): for port_name in port_names: if (port_name[0][0][len(port_name[0][0]) - 1] == port_id[0][1]): ports.append( Port(port_name[0][1], tagged, port_number)) return ports
def __deleteVLAN(self, vlan_name): """\brief Creates a vlan given an name \param vlan_name (\c string) vlan name to delete \return (\int) 0 if the operation is successful, -1 if it failed. """ # you delete a vlan by using its ifindex. # get vlan ifindex from vlan_name vlan_ifindex = self.__getVLANInternalID(vlan_name) log.debug("Deleting vlan with name " + str(vlan_name) + " and ifindex" + str(vlan_ifindex) + " on switch " + str(self.getSwitchName())) # check that we got a sane ifindex if vlan_ifindex == -1: log.debug("When deleting vlan with name " + str(vlan_id) + " couldn't get ifindex on switch " + str(self.getSwitchName())) return -1 # use snmp to delete the vlan self.snmp.set( \ OID.dot1qVlanStaticRowStatus+(vlan_ifindex,) ,\ rfc1902.Integer32(6) ) # check to see whether the set worked if self.snmp.getErrorStatus(): log.debug("Error deleting vlan with name " + str(vlan_name) + " and ifindex" + str(vlan_ifindex) + " on switch " + str(self.getSwitchName())) return -1 return 0
class BulkPDU(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('request-id', rfc1902.Integer32()), namedtype.NamedType('non-repeaters', _nonRepeaters), namedtype.NamedType('max-repetitions', _maxRepetitions), namedtype.NamedType('variable-bindings', VarBindList()) )
def __coerce_value(initial_value, new_value): """Coerce the new_value to the same type as the initial_value. :param initial_value: initial value from the device :param new_value: new value to set, coerced into the right type :return: new value, coerced into the right type """ # pylint: disable=redefined-variable-type # In order to return the right type the return value has to be # redefined. # Types from RFC-1902 if isinstance(initial_value, rfc1902.Counter32): set_value = rfc1902.Counter32(str(new_value)) elif isinstance(initial_value, rfc1902.Counter64): set_value = rfc1902.Counter64(str(new_value)) elif isinstance(initial_value, rfc1902.Gauge32): set_value = rfc1902.Gauge32(str(new_value)) elif isinstance(initial_value, rfc1902.Integer): set_value = rfc1902.Integer(str(new_value)) elif isinstance(initial_value, rfc1902.Integer32): set_value = rfc1902.Integer32(str(new_value)) elif isinstance(initial_value, rfc1902.IpAddress): set_value = rfc1902.IpAddress(str(new_value)) elif isinstance(initial_value, rfc1902.OctetString): set_value = rfc1902.OctetString(str(new_value)) elif isinstance(initial_value, rfc1902.TimeTicks): set_value = rfc1902.TimeTicks(str(new_value)) elif isinstance(initial_value, rfc1902.Unsigned32): set_value = rfc1902.Unsigned32(str(new_value)) else: raise RuntimeError("Unknown type %s" % type(initial_value)) return set_value
def _switchport_mode_trunk_init(self, nos_host, port_num): """Enable a port as VLAN trunk mode.""" LOG.debug(_('_switchport_mode_trunk_init %s %d'), nos_host, port_num) oid_table = self._get_oid_table(nos_host) """Change switchport to trunk mode, and set PVID = 1""" varBinds = [] TAGGED = 2 snmp_oid = oid_enterprise + oid_table['agPortNewCfgVlanTag'] + (port_num,) value = rfc1902.Integer(TAGGED) varBinds += (snmp_oid, value), snmp_oid = oid_enterprise + oid_table['agPortNewCfgPVID'] + (port_num,) value = rfc1902.Integer32(1) varBinds += (snmp_oid, value), self._set(nos_host, varBinds) """Remove all other VLAN except 1 for the first time config this port""" max_vlan_id = 4094 vlans = range(2, max_vlan_id+1) varBinds = [] for vid in vlans: snmp_oid = oid_enterprise + oid_table['vlanNewCfgRemovePort'] + (vid,) value = rfc1902.Gauge32(port_num) varBinds += (snmp_oid, value), if vid%20 == 0: self._set(nos_host, varBinds) varBinds = [] self._set(nos_host, varBinds)
def createVLAN(self, vlan): vlanName = vlan.getName() vlanNames = self.getVLANNames() for name in vlanNames.values(): if (str(name) == str(vlanName)): return -1 self.snmp.set(OID.netgearVlanStaticRowStatus + (vlan.getID(), ), rfc1902.Integer32(5)) if self.snmp.getErrorStatus(): print "Error with creating vlan row" print self.snmp return -2 self.snmp.set(OID.netgearVlanStaticName + (vlan.getID(), ), rfc1902.OctetString(vlan.getName())) if self.snmp.getErrorStatus(): print "Error with setting vlan name" print self.snmp return -3 # Now add the ports to the vlan if (self.addPorts(vlan.getName(), vlan.getPortsOnSwitch(self.getSwitchName())) < 0): return -4 return 0
class PDU(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('request-id', rfc1902.Integer32()), namedtype.NamedType('error-status', _errorStatus), namedtype.NamedType('error-index', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, max_bindings))), namedtype.NamedType('variable-bindings', VarBindList()) )
def _update_wattage(self, wattage): """Update OID associated with the current wattage draw""" oid = self.get_oid_by_name("WattageDraw") if not oid: return self._update_oid_value(oid, snmp_data_types.Integer32(max(wattage, 0)))
def deleteVLAN(self, vlanName): """\brief Deletes the vlan indicated by the given vlan name. This function will delete the vlan regardless of whether it contains ports or not and returns the following codes: -1: if the vlan does not exist on the switch -2: if the operation to delete the vlan's 802.1Q failed -3: if the snmpset command to delete the vlan fails 0: if successful \param vlanName (\c string) The name of the vlan to delete \return (\c int) 0 if successful, negative otherwise """ vi = self.getFullVLANInfo(vlanName) if len(vi) == 1: vlan = vi[0] else: return -1 if (vlan.getInternalID() == -1): return -1 # delete ports res = self.deletePorts(vlanName, vlan.getPortsOnSwitch(self.getSwitchName())) if res != 0: print "problem deleting ports in vlan" return -3 # First delete any 802.1Q interfaces associated with this vlan if vlan.getTaggedID() != None: self.snmp.set( OID.ifStackStatus + (vlan.getInternalID(), vlan.getTaggedID()), rfc1902.Integer(6)) if self.snmp.getErrorStatus(): print "unable to delete tagged vlan entry interface" print self.snmp print -3 self.snmp.set( OID.extremeVlanTaggedRowStatus + (vlan.getTaggedID(), ), rfc1902.Integer32(6)) if self.snmp.getErrorStatus(): print "unable to delete tagged interface" print self.snmp print -3 # At this point we have a valid vlan, delete it (this command deletes the # vlan regardless of whether it contains ports or not self.snmp.set( OID.extremeVlanStaticRowStatus + (vlan.getInternalID(), ), rfc1902.Integer(6)) if self.snmp.getErrorStatus(): print "Error with deleting vlan : " #+str(mylist[int(self.snmp.getErrorIndex())-1]) print self.snmp return -3 return 0
class BulkPDU(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('request-id', rfc1902.Integer32()), namedtype.NamedType( 'non-repeaters', univ.Integer().subtype( subtypeSpec=constraint.ValueRangeConstraint(0, max_bindings))), namedtype.NamedType( 'max-repetitions', univ.Integer().subtype( subtypeSpec=constraint.ValueRangeConstraint(0, max_bindings))), namedtype.NamedType('variable-bindings', VarBindList()))
class __WritePduGenerator(__ReadPduGenerator): _typeMap = { 'i': rfc1902.Integer(), 'u': rfc1902.Integer32(), 's': rfc1902.OctetString(), 'n': univ.Null(), 'o': univ.ObjectIdentifier(), 't': rfc1902.TimeTicks(), 'a': rfc1902.IpAddress() } def n_VarType(self, cbCtx, node): snmpEngine, ctx = cbCtx ctx['varType'] = node[0].attr def n_VarValue(self, cbCtx, node): snmpEngine, ctx = cbCtx ctx['varValue'] = node[0].attr def n_VarBind_exit(self, cbCtx, node): snmpEngine, ctx = cbCtx mibViewCtl = ctx['mibViewController'] if ctx['varType'] == '=': modName, nodeDesc, suffix = mibViewCtl.getNodeLocation( ctx['varName']) mibNode, = mibViewCtl.mibBuilder.importSymbols(modName, nodeDesc) if hasattr(mibNode, 'syntax'): MibTableColumn, = mibViewCtl.mibBuilder.importSymbols( 'SNMPv2-SMI', 'MibTableColumn') if isinstance(mibNode, MibTableColumn) or suffix == (0, ): val = mibNode.syntax else: raise error.PySnmpError( 'Found MIB scalar %s but non-scalar given %s' % (mibNode.name + (0, ), ctx['varName'])) else: raise error.PySnmpError('Variable %s has no syntax' % (ctx['varName'], )) else: try: val = self._typeMap[ctx['varType']] except KeyError: raise error.PySnmpError('unsupported SNMP value type \"%s\"' % ctx['varType']) try: val = val.clone(ctx['varValue']) except PyAsn1Error: raise error.PySnmpError(sys.exc_info()[1]) if 'varBinds' not in ctx: ctx['varBinds'] = [(ctx['varName'], val)] else: ctx['varBinds'].append((ctx['varName'], val))
def deleteVLAN(self, vlanName): vlanNames = self.getVLANNames() for vlanId in vlanNames: if vlanNames[vlanId] == vlanName: self.snmp.set(OID.netgearVlanStaticRowStatus + (vlanId, ), rfc1902.Integer32(6)) if self.snmp.getErrorStatus(): print "error deleting vlan" return -1 else: return 0 return -2
def dispatch(self): # Build and submit notification message to dispatcher self.sendNotification( self.snmpEngine, # Notification targets 'sendShutdownTrap', # Trap OID (IGFAE-USC-MIB::temperatureCritical) self.trap.name, # ( (oid, value), ... ) ( (self.roomTemp.name + (0, ), rfc1902.Integer32(self.temperature)), )) # Run I/O dispatcher which would send pending message and process response self.snmpEngine.transportDispatcher.runDispatcher()
def getPortInternalID(self, portNumber): """\brief Given a port's external number, this function returns its internal number. If the port is not found -1 is returned \param portNumber (\c string) The port number whose internal port is to be searched \return (\c string) The port's internal id, or -1 if unsuccessful """ varBindTable = self.getPortIDs() for tableRow in varBindTable: for name, val in tableRow: #print name,val if name is None: continue if name[len(name)-1] == rfc1902.Integer32(portNumber): return val return -1
def test__get_mac_addresses(self, snmpclient_mock): # NOTE(yushiro): In pysnmp 4.4.12, SNMPClient returns following type: # node classes: pysnmp.proto.rfc1902.Integer32 # mac addresses: pysnmp.proto.rfc1902.OctetString snmpclient_mock.return_value = mock.Mock( **{ 'get_next.side_effect': [[ rfc1902.Integer32(2), rfc1902.Integer32(2), rfc1902.Integer32(7) ], [ rfc1902.OctetString('\x90\x1b\x0e\xa5\x70\x37'), rfc1902.OctetString('\x90\x1b\x0e\xa5\x70\x38'), rfc1902.OctetString('\x90\x1b\x0e\xa5\x70\x39') ]] }) inspected_macs = ['90:1b:0e:a5:70:37', '90:1b:0e:a5:70:38'] with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: result = irmc_inspect._get_mac_addresses(task.node) self.assertEqual(inspected_macs, result)
def _parse_response(self, oid, value): if (self._stop_oid and oid >= self._stop_oid) or value.tagSet in self.TAGS_TO_SKIP: return True elif value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) elif value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) elif value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) response = SnmpResponse(oid, value, snmp_engine=self._snmp_engine, logger=self._logger) self.result.add(response) return False
def __deleteVLANByIfindex(self, vlan_ifindex): """\brief Creates a vlan given an name \param vlan_name (\c string) vlan name to delete \return (\int) 0 if the operation is successful, -1 if it failed. """ # you delete a vlan by using its ifindex. log.debug("Deleting vlan with ifindex " + str(vlan_ifindex) + " on switch " + str(self.getSwitchName())) # use snmp to delete the new vlan self.snmp.set(OID.dot1qVlanStaticRowStatus+(vlan_ifindex,) ,\ rfc1902.Integer32(6) ) # check to see whether the set worked if self.snmp.getErrorStatus(): log.debug("Error deleting vlan with and ifindex" + str(vlan_ifindex) + " on switch " + str(self.getSwitchName())) return -1 return 0
def _switchport_mode_trunk_init(self, nos_host, port_num): """Enable a port as VLAN trunk mode.""" LOG.debug(_('_switchport_mode_trunk_init %s %d'), nos_host, port_num) oid_table = self._get_oid_table(nos_host) """Change switchport to trunk mode, and set PVID = 1""" varBinds = [] TAGGED = 2 snmp_oid = oid_enterprise + oid_table['agPortNewCfgVlanTag'] + (port_num,) value = rfc1902.Integer(TAGGED) varBinds += (snmp_oid, value), snmp_oid = oid_enterprise + oid_table['agPortNewCfgPVID'] + (port_num,) value = rfc1902.Integer32(1) varBinds += (snmp_oid, value), self._set(nos_host, varBinds) """Remove all other VLAN except 1 for the first time config this port""" try: switchHW = oid_table["device"] except KeyError: switchHW = "" if switchHW == "Piglet":#vlan range always 1-4094 for piglet, different from other switches max_vlan_id = 4094 else: max_vlan_id = 4094 if self._support_old_release(nos_host) else 4095 vlans = range(2, max_vlan_id+1) varBinds = [] for vid in vlans: snmp_oid = oid_enterprise + oid_table['vlanNewCfgRemovePort'] + (vid,) value = rfc1902.Gauge32(port_num) varBinds += (snmp_oid, value), if vid%20 == 0: self._set(nos_host, varBinds) varBinds = [] self._set(nos_host, varBinds)
def _to_pysnmp(self, value): """ Convert connection plugin object into pysnmp objects """ if value is None: return None if isinstance(value, OctetString): return rfc1902.OctetString(str(value.value)) if isinstance(value, ObjectIdentifier): return rfc1902.ObjectName(str(value.value)) if isinstance(value, Integer32): return rfc1902.Integer32(int(value.value)) if isinstance(value, Counter32): return rfc1902.Counter32(long(value.value)) if isinstance(value, IpAddress): return rfc1902.IpAddress(str(value.value)) if isinstance(value, Gauge32): return rfc1902.Gauge32(long(value.value)) if isinstance(value, TimeTicks): return rfc1902.TimeTicks(long(value.value)) if isinstance(value, Opaque): return rfc1902.Opaque(value.value) # FIXME if isinstance(value, Counter64): return rfc1902.Counter64(str(value.value)) raise SnmpError('Invalid type: %s' % value.__class__.__name__)
def getSensorReadings(self): """\brief Returns a dictionary of the form: {sensorclass:{sensorname:reading}}. The reading will either be a numeric value (no units of measurements are given in the value) or -1 for sensors that could not be read. """ # Grab the chassis temperature sensorResults = self.getEmptySensorDictionary() tempClass = self.getSensorClassFromName( \ self.SENSOR_DESCRIPTIONS, "chassistemp") tempReading = self.snmp.get(OID.extremeCurrentTemperature)[0][1] if not self.snmp.getErrorStatus() and tempClass: (sensorResults[tempClass])["chassistemp"] = int(tempReading) # Grab the overtemp alarm status overtempClass = self.getSensorClassFromName( \ self.SENSOR_DESCRIPTIONS, "overtemp") overtempReading = self.snmp.get(OID.extremeOverTemperatureAlarm)[0][1] if not self.snmp.getErrorStatus() and tempClass: if overtempReading != 2: (sensorResults[overtempClass])["overtemp"] = 1 # ALARM else: (sensorResults[overtempClass])["overtemp"] = 0 # OK # Grab the fan alarm statuses fantable = self.snmp.walk(OID.extremeFanStatusTable) for fantablerow in fantable: fanName = "fan" + \ str(fantablerow[0][0][len(fantablerow[0][0])-1]) fanClass = self.getSensorClassFromName( \ self.SENSOR_DESCRIPTIONS, fanName) if fanClass: if fantablerow[0][1] != rfc1902.Integer32('1'): (sensorResults[fanClass])[fanName] = 1 # ALARM else: (sensorResults[fanClass])[fanName] = 0 # OK return sensorResults
class PDU(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('request-id', rfc1902.Integer32()), namedtype.NamedType( 'error-status', univ.Integer(namedValues=namedval.NamedValues(('noError', 0), ( 'tooBig', 1), ('noSuchName', 2), ('badValue', 3), ('readOnly', 4), ( 'genErr', 5), ('noAccess', 6), ('wrongType', 7), ( 'wrongLength', 8), ('wrongEncoding', 9), ('wrongValue', 10), ( 'noCreation', 11), ('inconsistentValue', 12), ( 'resourceUnavailable', 13), ( 'commitFailed', 14), ('undoFailed', 15), ('authorizationError', 16), ('notWritable', 17), ('inconsistentName', 18)))), namedtype.NamedType( 'error-index', univ.Integer().subtype( subtypeSpec=constraint.ValueRangeConstraint(0, max_bindings))), namedtype.NamedType('variable-bindings', VarBindList()))
def variate(oid, tag, value, **context): if 'settings' not in recordContext: recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'dir' not in recordContext['settings']: log.msg('multiplex: snapshot directory not specified') return context['origOid'], tag, context['errorStatus'] recordContext['settings']['dir'] = recordContext['settings'][ 'dir'].replace('/', os.path.sep) if recordContext['settings']['dir'][0] != os.path.sep: for x in confdir.data: d = os.path.join(x, recordContext['settings']['dir']) if os.path.exists(d): break else: log.msg('multiplex: directory %s not found' % recordContext['settings']['dir']) return context['origOid'], tag, context['errorStatus'] else: d = recordContext['settings']['dir'] recordContext['dirmap'] = dict([ (int(os.path.basename(x).split(os.path.extsep)[0]), os.path.join(d, x)) for x in os.listdir(d) if x[-7:] == 'snmprec' ]) recordContext['keys'] = list(recordContext['dirmap'].keys()) recordContext['bounds'] = (min(recordContext['keys']), max(recordContext['keys'])) if 'period' in recordContext['settings']: recordContext['settings']['period'] = float( recordContext['settings']['period']) else: recordContext['settings']['period'] = 60.0 if 'wrap' in recordContext['settings']: recordContext['settings']['wrap'] = bool( recordContext['settings']['wrap']) else: recordContext['settings']['wrap'] = False if 'control' in recordContext['settings']: recordContext['settings']['control'] = rfc1902.ObjectName( recordContext['settings']['control']) log.msg( 'multiplex: using control OID %s for subtree %s, time-based multiplexing disabled' % (recordContext['settings']['control'], oid)) recordContext['ready'] = True if 'ready' not in recordContext: return context['origOid'], tag, context['errorStatus'] if oid not in moduleContext: moduleContext[oid] = {} if context['setFlag']: if 'control' in recordContext['settings'] and \ recordContext['settings']['control'] == context['origOid']: fileno = int(context['origValue']) if fileno >= len(recordContext['keys']): log.msg('multiplex: .snmprec file number %s over limit of %s' % (fileno, len(recordContext['keys']))) return context['origOid'], tag, context['errorStatus'] moduleContext[oid]['fileno'] = fileno log.msg('multiplex: switched to file #%s (%s)' % (recordContext['keys'][fileno], recordContext['dirmap'][recordContext['keys'][fileno]])) return context['origOid'], tag, context['origValue'] else: return context['origOid'], tag, context['errorStatus'] if 'control' in recordContext['settings']: if 'fileno' not in moduleContext[oid]: moduleContext[oid]['fileno'] = 0 if (not context['nextFlag'] and recordContext['settings']['control'] == context['origOid']): return context['origOid'], tag, rfc1902.Integer32( moduleContext[oid]['fileno']) else: timeslot = (time.time() - moduleContext['booted']) % ( recordContext['settings']['period'] * len(recordContext['dirmap'])) fileslot = int( timeslot / recordContext['settings']['period']) + recordContext['bounds'][0] fileno = bisect.bisect(recordContext['keys'], fileslot) - 1 if ('fileno' not in moduleContext[oid] or moduleContext[oid]['fileno'] < fileno or recordContext['settings']['wrap']): moduleContext[oid]['fileno'] = fileno datafile = recordContext['dirmap'][recordContext['keys'][moduleContext[oid] ['fileno']]] if ('datafile' not in moduleContext[oid] or moduleContext[oid]['datafile'] != datafile): if 'datafileobj' in moduleContext[oid]: moduleContext[oid]['datafileobj'].close() moduleContext[oid]['datafileobj'] = RecordIndex( datafile, SnmprecRecord()).create() moduleContext[oid]['datafile'] = datafile log.msg('multiplex: switching to data file %s for %s' % (datafile, context['origOid'])) text, db = moduleContext[oid]['datafileobj'].getHandles() textOid = str( rfc1902.OctetString('.'.join(['%s' % x for x in context['origOid']]))) try: line = moduleContext[oid]['datafileobj'].lookup(textOid) except KeyError: offset = searchRecordByOid(context['origOid'], text, SnmprecRecord()) exactMatch = False else: offset, subtreeFlag, prevOffset = line.split(str2octs(',')) exactMatch = True text.seek(int(offset)) line, _, _ = getRecord(text) # matched line if context['nextFlag']: if exactMatch: line, _, _ = getRecord(text) else: if not exactMatch: return context['origOid'], tag, context['errorStatus'] if not line: return context['origOid'], tag, context['errorStatus'] try: oid, value = SnmprecRecord().evaluate(line) except error.SnmpsimError: oid, value = context['origOid'], context['errorStatus'] return oid, tag, value
def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, cbCtx): if errorIndication and not cbCtx['retries']: cbCtx['errors'] += 1 log.error('SNMP Engine error: %s' % errorIndication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if errorStatus and errorStatus != 2 or errorIndication: log.error('Remote SNMP error %s' % (errorIndication or errorStatus.prettyPrint())) if cbCtx['retries']: try: nextOID = varBindTable[-1][0][0] except IndexError: nextOID = cbCtx['lastOID'] else: log.error('Failed OID: %s' % nextOID) # fuzzy logic of walking a broken OID if len(nextOID) < 4: pass elif (continueOnErrors - cbCtx['retries']) * 10 / continueOnErrors > 5: nextOID = nextOID[:-2] + (nextOID[-2] + 1, ) elif nextOID[-1]: nextOID = nextOID[:-1] + (nextOID[-1] + 1, ) else: nextOID = nextOID[:-2] + (nextOID[-2] + 1, 0) cbCtx['retries'] -= 1 cbCtx['lastOID'] = nextOID log.info('Retrying with OID %s (%s retries left)...' % (nextOID, cbCtx['retries'])) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [(nextOID, None)], cbFun, cbCtx) else: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, [(nextOID, None)], cbFun, cbCtx) cbCtx['errors'] += 1 return if continueOnErrors != cbCtx['retries']: cbCtx['retries'] += 1 if varBindTable and varBindTable[-1] and varBindTable[-1][0]: cbCtx['lastOID'] = varBindTable[-1][0][0] stopFlag = False # Walk var-binds for varBindRow in varBindTable: for oid, value in varBindRow: # EOM if stopOID and oid >= stopOID: stopFlag = True # stop on out of range condition elif (value is None or value.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet)): stopFlag = True # remove value enumeration if value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) if value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) if value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) # Build .snmprec record context = { 'origOid': oid, 'origValue': value, 'count': cbCtx['count'], 'total': cbCtx['total'], 'iteration': cbCtx['iteration'], 'reqTime': cbCtx['reqTime'], 'startOID': startOID, 'stopOID': stopOID, 'stopFlag': stopFlag, 'variationModule': variationModule } try: line = dataFileHandler.format(oid, value, **context) except error.MoreDataNotification: cbCtx['count'] = 0 cbCtx['iteration'] += 1 moreDataNotification = sys.exc_info()[1] if 'period' in moreDataNotification: log.info('%s OIDs dumped, waiting %.2f sec(s)...' % (cbCtx['total'], moreDataNotification['period'])) time.sleep(moreDataNotification['period']) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [(startOID, None)], cbFun, cbCtx) else: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, [(startOID, None)], cbFun, cbCtx) stopFlag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError: log.error((sys.exc_info()[1], )) continue else: outputFile.write(line) cbCtx['count'] += 1 cbCtx['total'] += 1 if cbCtx['count'] % 100 == 0: log.error('OIDs dumped: %s/%s' % (cbCtx['iteration'], cbCtx['count'])) # Next request time cbCtx['reqTime'] = time.time() # Continue walking return not stopFlag