def _convert_row_to_container(self, netbox, ifindex, row): """Convert a collected ifTable/ifXTable row into a container object.""" interface = self.containers.factory(ifindex, shadows.Interface) interface.ifindex = ifindex interface.ifdescr = row['ifDescr'] interface.iftype = row['ifType'] speed = self._extract_interface_speed( row["ifSpeed"], row["ifHighSpeed"], always_use_highspeed=self.config.getboolean( "interfaces", "always_use_ifhighspeed" ), ) if speed is not None: interface.speed = speed interface.ifphysaddress = typesafe_binary_mac_to_hex(row['ifPhysAddress']) interface.ifadminstatus = row['ifAdminStatus'] interface.ifoperstatus = row['ifOperStatus'] interface.ifname = row['ifName'] or interface.baseport or row['ifDescr'] interface.ifconnectorpresent = row['ifConnectorPresent'] == 1 interface.ifalias = safestring(row['ifAlias']) # Set duplex if sucessfully retrieved if 'duplex' in row and row['duplex'] in DUPLEX_MAP: interface.duplex = DUPLEX_MAP[row['duplex']] interface.gone_since = None interface.netbox = netbox return interface
def _convert_row_to_container(self, netbox, ifindex, row): """Convert a collected ifTable/ifXTable row into a container object.""" interface = self.containers.factory(ifindex, shadows.Interface) interface.ifindex = ifindex interface.ifdescr = row['ifDescr'] interface.iftype = row['ifType'] # ifSpeed spec says to use ifHighSpeed if the 32-bit unsigned # integer is maxed out if row['ifSpeed'] is not None and row['ifSpeed'] < 4294967295: interface.speed = row['ifSpeed'] / 1000000.0 elif row['ifHighSpeed'] is not None: interface.speed = float(row['ifHighSpeed']) interface.ifphysaddress = binary_mac_to_hex(row['ifPhysAddress']) interface.ifadminstatus = row['ifAdminStatus'] interface.ifoperstatus = row['ifOperStatus'] interface.ifname = row['ifName'] or interface.baseport or row['ifDescr'] interface.ifconnectorpresent = row['ifConnectorPresent'] == 1 interface.ifalias = safestring(row['ifAlias']) # Set duplex if sucessfully retrieved if 'duplex' in row and row['duplex'] in DUPLEX_MAP: interface.duplex = DUPLEX_MAP[row['duplex']] interface.gone_since = None interface.netbox = netbox return interface
def snmp_write_test(ip, profile): """Test that snmp write works""" testresult = { 'error_message': '', 'custom_error': '', 'status': False, 'syslocation': '' } syslocation = '1.3.6.1.2.1.1.6.0' value = '' try: snmp = Snmp( ip, profile.configuration.get("community"), profile.configuration.get("version"), ) value = safestring(snmp.get(syslocation)) snmp.set(syslocation, 's', value.encode('utf-8')) except SnmpError as error: testresult['error_message'] = error.args testresult['status'] = False except UnicodeDecodeError as error: testresult['custom_error'] = 'UnicodeDecodeError' testresult['error_message'] = error.args testresult['status'] = False else: testresult['status'] = True testresult['syslocation'] = value return testresult
def _container_from_entity(self, ent): device_key = 'ENTITY-MIB:' + str(ent.get(0)) container = self.containers.factory(device_key, NetboxEntity) netbox = self.containers.factory(None, shadows.Netbox) container.netbox = netbox container.index = ent.get(0) container.source = 'ENTITY-MIB' for attr, column in self.field_map.items(): value = ent.get(column) if column in EntityMib.text_columns and value and "\x00" in value: value = value.replace("\x00", "") # Remove broken stuff from text if column in ("entPhysicalVendorType", "entPhysicalUris") and value: value = safestring(value).replace("\x00", "") if column == 'entPhysicalClass': value = self.class_map.get(value) if value is not None: setattr(container, attr, value) if getattr(container, 'serial', None): device = self.containers.factory(container.serial, shadows.Device) device.serial = container.serial for key in ('hardware', 'firmware', 'software'): val = getattr(container, key + '_revision') if val: setattr(device, key + '_version', val) device.active = True container.device = device return container
def snmp_write_test(ip, community, snmp_version): """Test that snmp write works""" if not community: return False testresult = { 'error_message': '', 'custom_error': '', 'status': False, 'syslocation': '' } syslocation = '1.3.6.1.2.1.1.6.0' value = '' try: snmp = Snmp(ip, community, snmp_version) value = safestring(snmp.get(syslocation)) snmp.set(syslocation, 's', value.encode('utf-8')) except SnmpError as error: try: value.decode('ascii') except UnicodeDecodeError: testresult['custom_error'] = 'UnicodeDecodeError' testresult['error_message'] = error.args testresult['status'] = False else: testresult['status'] = True testresult['syslocation'] = value return testresult
def _get_all_ifaliases(self): """Get all aliases for all interfaces. :returns: A dict describing {ifIndex: ifAlias} """ return { OID(oid)[-1]: safestring(value) for oid, value in self._bulkwalk(self.IF_ALIAS_OID) }
def _result_formatter(result): formatted_result = {} # result keys may be OID objects/tuples or strings, depending on # snmp library used if node.oid not in result and str(node.oid) not in result: self._logger.debug("%s (%s) seems to be unsupported, result " "keys were: %r", column_name, node.oid, result.keys()) return {} varlist = result.get(node.oid, result.get(str(node.oid), None)) for oid, value in varlist.items(): # Extract index information from oid row_index = OID(oid).strip_prefix(node.oid) if column_name in self.text_columns: value = safestring(value) formatted_result[row_index] = value return formatted_result
def _response_to_metrics(self, result, sensors, netboxes): metrics = [] timestamp = time.time() data = ((sensors[oid], value) for oid, value in result.items() if oid in sensors) for sensor, value in data: # Attempt to support numbers-as-text values if isinstance(value, bytes): value = safestring(value) if isinstance(value, str): try: value = float(value) except ValueError: pass value = convert_to_precision(value, sensor) for netbox in netboxes: path = metric_path_for_sensor(netbox, sensor['internal_name']) metrics.append((path, (timestamp, value))) send_metrics(metrics) return metrics
def _result_formatter(result): formatted_result = {} for varlist in result.values(): # Build a table structure for oid in sorted(varlist.keys()): if not table.table.oid.is_a_prefix_of(oid): _msg = "Received wrong response from client, %s is not in %s" raise MibRetrieverError(_msg % (oid, table.table.oid)) # Extract table position of value oid_suffix = OID(oid).strip_prefix(table.row.oid) column_no = oid_suffix[0] row_index = oid_suffix[1:] if column_no not in table.reverse_column_index: self._logger.warning( "device response has bad table index %s in %s::%s, " "ignoring", oid_suffix, self.mib['moduleName'], table_name, ) continue column_name = table.reverse_column_index[column_no] if row_index not in formatted_result: formatted_result[row_index] = MibTableResultRow( row_index, table.columns.keys(), ) value = varlist[oid] if column_name in self.text_columns: value = safestring(value) formatted_result[row_index][column_name] = value return formatted_result
def get_if_alias(self, if_index): return safestring(self._query_netbox(self.IF_ALIAS_OID, if_index))
def _get_interface_names(self) -> Dict[int, str]: """Returns a mapping of interface indexes to ifName values""" return { OID(index)[-1]: safestring(value) for index, value in self._bulkwalk(self.IF_NAME_OID) }
def test_latin1_encoded_ifalias_should_be_properly_decoded(self): result = safestring(b'A m\xf8\xf8se once bit my sister') expected = u'A m\xf8\xf8se once bit my sister' self.assertEqual(result, expected)
def test_number_should_be_encoded(self): result = safestring(42) self.assertEqual(result, "42")
def test_unknown_encoding_should_not_raise_error(self): result = safestring(b'A m\x9b\x9bse once bit my sister') self.assertTrue(isinstance(result, str))
def test_none_should_be_returned_unchanged(self): result = safestring(None) self.assertTrue(result is None)
def get_all_if_alias(self): return { OID(oid)[-1]: safestring(value) for oid, value in self._bulkwalk(self.IF_ALIAS_OID) }
def get_if_alias(self, if_index): """ Get alias on a specific interface """ return safestring(self._query_netbox(self.IF_ALIAS_OID, if_index))