Ejemplo n.º 1
0
def get_node(conn):
    node = {}
    name = SnmpApi.ObjectType(
        SnmpApi.ObjectIdentity('SNMPv2-MIB', 'sysName', 0))
    descr = SnmpApi.ObjectType(
        SnmpApi.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))

    errorIndication, errorStatus, errorIndex, varBinds = next(
        SnmpApi.getCmd(conn['snmpEng'], conn['community'], conn['target'],
                       conn['context'], name, descr))

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' %
              (errorStatus.prettyPrint(),
               errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
    else:
        for varBind in varBinds:
            (oid, value) = [x.prettyPrint() for x in varBind]
            if value is None:
                continue

            if re.search('sysName', oid):
                node['name'] = value
            elif re.search('sysDescr', oid):
                node['descr'] = value

    return node
Ejemplo n.º 2
0
    def parse_metrics(metrics, enforce_constraints, warning):
        """Parse configuration and returns data to be used for SNMP queries.

        `raw_oids` is a list of SNMP numerical OIDs to query.
        `table_oids` is a dictionnary of SNMP tables to symbols to query.
        `mibs_to_load` contains the relevant MIBs used for querying.
        """
        raw_oids = []
        table_oids = {}
        mibs_to_load = set()
        # Check the metrics completely defined
        for metric in metrics:
            if 'MIB' in metric:
                if not ('table' in metric or 'symbol' in metric):
                    raise ConfigurationError('When specifying a MIB, you must specify either table or symbol')
                if not enforce_constraints:
                    # We need this only if we don't enforce constraints to be able to lookup MIBs manually
                    mibs_to_load.add(metric['MIB'])
                if 'symbol' in metric:
                    to_query = metric['symbol']
                    try:
                        table_oids[hlapi.ObjectType(hlapi.ObjectIdentity(metric['MIB'], to_query))] = []
                    except Exception as e:
                        warning("Can't generate MIB object for variable : %s\nException: %s", metric, e)
                elif 'symbols' not in metric:
                    raise ConfigurationError('When specifying a table, you must specify a list of symbols')
                else:
                    symbols = []
                    table_oids[hlapi.ObjectType(hlapi.ObjectIdentity(metric['MIB'], metric['table']))] = symbols
                    for symbol in metric['symbols']:
                        try:
                            symbols.append(hlapi.ObjectType(hlapi.ObjectIdentity(metric['MIB'], symbol)))
                        except Exception as e:
                            warning("Can't generate MIB object for variable : %s\nException: %s", metric, e)
                    if 'metric_tags' in metric:
                        for metric_tag in metric['metric_tags']:
                            if not ('tag' in metric_tag and ('index' in metric_tag or 'column' in metric_tag)):
                                raise ConfigurationError(
                                    'When specifying metric tags, you must specify a tag, and an index or column'
                                )
                            if 'column' in metric_tag:
                                # In case it's a column, we need to query it as well
                                try:
                                    symbols.append(
                                        hlapi.ObjectType(hlapi.ObjectIdentity(metric['MIB'], metric_tag.get('column')))
                                    )
                                except Exception as e:
                                    warning("Can't generate MIB object for variable : %s\nException: %s", metric, e)

            elif 'OID' in metric:
                raw_oids.append(hlapi.ObjectType(hlapi.ObjectIdentity(metric['OID'])))
            else:
                raise ConfigurationError('Unsupported metric in config file: {}'.format(metric))

        return table_oids, raw_oids, mibs_to_load
Ejemplo n.º 3
0
def get_ifs(conn):
    ifs = {}

    iftype = SnmpApi.ObjectType(SnmpApi.ObjectIdentity('IF-MIB', 'ifType'))
    ifname = SnmpApi.ObjectType(SnmpApi.ObjectIdentity('IF-MIB', 'ifName'))
    ifdescr = SnmpApi.ObjectType(SnmpApi.ObjectIdentity('IF-MIB', 'ifDescr'))
    ifalias = SnmpApi.ObjectType(SnmpApi.ObjectIdentity('IF-MIB', 'ifAlias'))

    for (errorIndication, errorStatus, errorIndex,
         varBinds) in SnmpApi.nextCmd(conn['snmpEng'],
                                      conn['community'],
                                      conn['target'],
                                      conn['context'],
                                      iftype,
                                      ifname,
                                      ifdescr,
                                      ifalias,
                                      lexicographicMode=False):
        if errorIndication:
            print(errorIndication)
            continue
        elif errorStatus:
            print('%s at %s' %
                  (errorStatus.prettyPrint(),
                   errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
            continue

        for varBind in varBinds:
            (oid, value) = [x.prettyPrint() for x in varBind]
            if value is None:
                continue

            index = (oid.split('.'))[-1]
            if index not in ifs:
                ifs[index] = {}

            if re.search('ifType', oid):
                label = 'ifType'
            elif re.search('ifName', oid):
                label = 'ifName'
            elif re.search('ifDescr', oid):
                label = 'ifDescr'
            elif re.search('ifAlias', oid):
                label = 'ifAlias'
            else:
                continue

            ifs[index][label] = value

    return ifs
Ejemplo n.º 4
0
 def parse_metric_tags(self, metric_tags):
     # type: (List[Dict[str, Any]]) -> Tuple[List[Any], List[ParsedMetricTag]]
     """Parse configuration for global metric_tags."""
     oids = []
     parsed_metric_tags = []
     for tag in metric_tags:
         if not ('symbol' in tag and 'tag' in tag):
             raise ConfigurationError(
                 "A metric tag needs to specify a symbol and a tag: {}".
                 format(tag))
         if not ('OID' in tag or 'MIB' in tag):
             raise ConfigurationError(
                 "A metric tag needs to specify an OID or a MIB: {}".format(
                     tag))
         symbol = tag['symbol']
         tag_name = tag['tag']
         if 'MIB' in tag:
             mib = tag['MIB']
             identity = hlapi.ObjectIdentity(mib, symbol)
         else:
             oid = tag['OID']
             identity = hlapi.ObjectIdentity(oid)
             self._resolver.register(to_oid_tuple(oid), symbol)
         object_type = hlapi.ObjectType(identity)
         oids.append(object_type)
         parsed_metric_tags.append(ParsedMetricTag(tag_name, symbol))
     return oids, parsed_metric_tags
Ejemplo n.º 5
0
def set(oid,
        value,
        host,
        port=161,
        community='private',
        timeout=0,
        retries=0,
        snmp_ver=2):
    try:
        for (err_i, err_st, err_idx, vals) in snmp_engine.setCmd(
                snmp_engine.SnmpEngine(),
                snmp_engine.CommunityData(community, mpModel=snmp_ver - 1),
                snmp_engine.UdpTransportTarget((host, port),
                                               timeout=timeout,
                                               retries=retries),
                snmp_engine.ContextData(),
                snmp_engine.ObjectType(snmp_engine.ObjectIdentity(oid),
                                       value)):
            if err_i or err_st:
                logging.debug('snmp error: %s' % err_i)
                return None
            else:
                return True
    except:
        log_traceback()
        return False
Ejemplo n.º 6
0
def snmpGet(snmpVersion, community, host, port, oids):

    logging.info('New Get Query [v:%d, %s, %s, %d, %s]', snmpVersion,
                 community, host, port, oids)

    objectTypes = [snmp.ObjectType(snmp.ObjectIdentity(oid)) for oid in oids]

    errorIndication, errorStatus, errorIndex, varBinds = next(
        snmp.getCmd(snmp.SnmpEngine(),
                    snmp.CommunityData(community, mpModel=snmpVersion),
                    snmp.UdpTransportTarget((host, port)), snmp.ContextData(),
                    *objectTypes))

    if errorIndication:
        logging.error(errorIndication)
        return None

    if errorStatus:
        logging.error('%s at %s', errorStatus.prettyPrint(),
                      errorIndex and varBinds[int(errorIndex) - 1][0] or '?')
        return None

    results = [(str(name), str(value)) for name, value in varBinds]

    return dict(results)
Ejemplo n.º 7
0
    def _autodetect(self):
        from pysnmp import hlapi

        for (errorIndication, errorStatus, errorIndex,
             varBindTable) in hlapi.getCmd(
                 hlapi.SnmpEngine(), hlapi.CommunityData('public'),
                 hlapi.UdpTransportTarget((self.hostname, 161)),
                 hlapi.ContextData(),
                 hlapi.ObjectType(
                     hlapi.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))):
            if errorIndication:
                Exception("snmp error {}".format(errorIndication))
            elif errorStatus:
                Exception("snmp error {}".format(errorStatus))
            else:
                sysDescr = str(varBindTable[0][1])

        if sysDescr.startswith("HPE OfficeConnect Switch 1820 24G J9980A,"):
            self._get_fdb = self._get_fdb_dot1q
        elif sysDescr.startswith("HP 1810-24G,"):
            self._get_fdb = self._get_fdb_dot1d
        else:
            Exception("unsupported switch {}".format(sysDescr))

        self.logger.debug("autodetected switch{}: {} {}".format(
            sysDescr, self._get_ports, self._get_fdb))
Ejemplo n.º 8
0
def set_oid_value(oid, value, host="localhost", port=1024):
    """Helper function to set snmp oid value of a device"""
    error_indicator, error_status, error_idx, var_binds = next(
        hlapi.setCmd(
            hlapi.SnmpEngine(),
            hlapi.CommunityData("private", mpModel=0),
            hlapi.UdpTransportTarget((host, port)),
            hlapi.ContextData(),
            hlapi.ObjectType(hlapi.ObjectIdentity(oid), value),
            lookupMib=False,
        )
    )

    if error_indicator:
        print(error_indicator)
    elif error_status:
        print(
            "%s at %s"
            % (
                error_status.prettyPrint(),
                error_idx and var_binds[int(error_idx) - 1][0] or "?",
            )
        )
    else:
        v_bind = var_binds[0]
        return v_bind[1]

    return None
Ejemplo n.º 9
0
    def _get_next(self, obj_identity):
        args = self.snmp_basic_info + (hlapi.ObjectType(obj_identity),)

        kwargs = {'lexicographicMode': False}

        result = {}

        for (errorIndication,
             errorStatus,
             errorIndex,
             varBinds) in hlapi.nextCmd(*args, **kwargs):
            if errorIndication:
                print(errorIndication)
                break
            elif errorStatus:
                print('%s at %s' % (errorStatus.prettyPrint(),
                                    errorIndex and
                                    varBinds[int(errorIndex) - 1][0] or '?'))
                break
            else:
                for varBind in varBinds:
                    res = self._parse_var_bind(varBind)
                    value = varBind[1]
                    if isinstance(value, rfc1902.Integer32):
                        result[res[1]] = int(res[2])
                    else:
                        result[res[1]] = varBind[1]._value.decode('utf-8')

        return result
Ejemplo n.º 10
0
    def fetch_oids(self, config, oids, enforce_constraints):
        # UPDATE: We used to perform only a snmpgetnext command to fetch metric values.
        # It returns the wrong value when the OID passeed is referring to a specific leaf.
        # For example:
        # snmpgetnext -v2c -c public localhost:11111 1.3.6.1.2.1.25.4.2.1.7.222
        # iso.3.6.1.2.1.25.4.2.1.7.224 = INTEGER: 2
        # SOLUTION: perform a snmpget command and fallback with snmpgetnext if not found
        error = None
        first_oid = 0
        all_binds = []
        while first_oid < len(oids):
            try:
                oids_batch = oids[first_oid:first_oid + self.oid_batch_size]
                self.log.debug('Running SNMP command get on OIDS %s',
                               oids_batch)
                error_indication, error_status, _, var_binds = next(
                    config.call_cmd(hlapi.getCmd,
                                    *oids_batch,
                                    lookupMib=enforce_constraints))
                self.log.debug('Returned vars: %s', var_binds)

                self.raise_on_error_indication(error_indication,
                                               config.ip_address)

                missing_results = []

                for var in var_binds:
                    result_oid, value = var
                    if reply_invalid(value):
                        oid_tuple = result_oid.asTuple()
                        missing_results.append(
                            hlapi.ObjectType(hlapi.ObjectIdentity(oid_tuple)))
                    else:
                        all_binds.append(var)

                if missing_results:
                    # If we didn't catch the metric using snmpget, try snmpnext
                    # Don't walk through the entire MIB, stop at end of table
                    self.log.debug('Running SNMP command getNext on OIDS %s',
                                   missing_results)
                    binds_iterator = config.call_cmd(
                        hlapi.nextCmd,
                        *missing_results,
                        lookupMib=enforce_constraints,
                        ignoreNonIncreasingOid=self.ignore_nonincreasing_oid,
                        lexicographicMode=False)
                    binds, error = self._consume_binds_iterator(
                        binds_iterator, config)
                    all_binds.extend(binds)

            except PySnmpError as e:
                message = 'Failed to collect some metrics: {}'.format(e)
                if not error:
                    error = message
                self.warning(message)

            # if we fail move onto next batch
            first_oid += self.oid_batch_size

        return all_binds, error
Ejemplo n.º 11
0
    def get(self, oid):
        """Use PySNMP to perform an SNMP GET operation on a single object.

        :param oid: The OID of the object to get.
        :raises: SNMPFailure if an SNMP request fails.
        :returns: The value of the requested object.
        """
        try:
            snmp_gen = snmp.getCmd(self.snmp_engine,
                                   self._get_auth(),
                                   self._get_transport(),
                                   self._get_context(),
                                   snmp.ObjectType(snmp.ObjectIdentity(oid)))

        except snmp_error.PySnmpError as e:
            raise exception.SNMPFailure(operation="GET", error=e)

        error_indication, error_status, error_index, var_binds = next(snmp_gen)

        if error_indication:
            # SNMP engine-level error.
            raise exception.SNMPFailure(operation="GET",
                                        error=error_indication)

        if error_status:
            # SNMP PDU error.
            raise exception.SNMPFailure(operation="GET",
                                        error=error_status.prettyPrint())

        # We only expect a single value back
        name, val = var_binds[0]
        return val
Ejemplo n.º 12
0
def snmpWalk(snmpVersion, community, host, port, oid):
    generator = snmp.nextCmd(snmp.SnmpEngine(),
                             snmp.CommunityData(community,
                                                mpModel=snmpVersion),
                             snmp.UdpTransportTarget((host, port)),
                             snmp.ContextData(),
                             snmp.ObjectType(snmp.ObjectIdentity(oid)),
                             lexicographicMode=False)

    results = dict()

    for errorIndication, errorStatus, errorIndex, varBinds in generator:
        if errorIndication:
            print(errorIndication)
            continue

        if errorStatus:
            print('%s at %s', errorStatus.prettyPrint(),
                  errorIndex and varBinds[int(errorIndex) - 1][0] or '?')
            continue

        for name, value in varBinds:
            results[str(name)] = str(value)

    return results
Ejemplo n.º 13
0
    def set(self, oid, value):
        """Use PySNMP to perform an SNMP SET operation on a single object.

        :param oid: The OID of the object to set.
        :param value: The value of the object to set.
        :raises: SNMPFailure if an SNMP request fails.
        """
        try:
            snmp_gen = snmp.setCmd(self.snmp_engine,
                                   self._get_auth(write_mode=True),
                                   self._get_transport(),
                                   self._get_context(),
                                   snmp.ObjectType(
                                       snmp.ObjectIdentity(oid), value))

        except snmp_error.PySnmpError as e:
            raise exception.SNMPFailure(operation="SET", error=e)

        error_indication, error_status, error_index, var_binds = next(snmp_gen)

        if error_indication:
            # SNMP engine-level error.
            raise exception.SNMPFailure(operation="SET",
                                        error=error_indication)

        if error_status:
            # SNMP PDU error.
            raise exception.SNMPFailure(operation="SET",
                                        error=error_status.prettyPrint())
Ejemplo n.º 14
0
def snmpWalk(snmpVersion, community, host, port, oid):

    logging.info('New Walk Query [v:%d, %s, %s, %d, %s]', snmpVersion,
                 community, host, port, oid)

    generator = snmp.nextCmd(snmp.SnmpEngine(),
                             snmp.CommunityData(community,
                                                mpModel=snmpVersion),
                             snmp.UdpTransportTarget((host, port)),
                             snmp.ContextData(),
                             snmp.ObjectType(snmp.ObjectIdentity(oid)),
                             lexicographicMode=False)

    results = dict()

    for errorIndication, errorStatus, errorIndex, varBinds in generator:
        if errorIndication:
            logging.error(errorIndication)
            raise Exception('SnmpWalk ErrorIndication.')

        if errorStatus:
            logging.error(
                '%s at %s', errorStatus.prettyPrint(),
                errorIndex and varBinds[int(errorIndex) - 1][0] or '?')
            raise Exception('SnmpWalk ErrorStatus.')

        for name, value in varBinds:
            results[str(name)] = str(value)

    return results
Ejemplo n.º 15
0
    def _get_fdb_dot1q(self):
        """Fetch the forwarding database via SNMP using the Q-BRIDGE-MIB

        Returns:
            Dict[List[str]]: ports and their values
        """
        from pysnmp import hlapi

        ports = {}

        for (errorIndication, errorStatus, errorIndex,
             varBindTable) in hlapi.bulkCmd(
                 hlapi.SnmpEngine(),
                 hlapi.CommunityData('public'),
                 hlapi.UdpTransportTarget((self.hostname, 161)),
                 hlapi.ContextData(),
                 0,
                 50,
                 hlapi.ObjectType(
                     hlapi.ObjectIdentity('Q-BRIDGE-MIB', 'dot1qTpFdbPort')),
                 lexicographicMode=False):
            if errorIndication:
                Exception("snmp error {}".format(errorIndication))
            elif errorStatus:
                Exception("snmp error {}".format(errorStatus))
            else:
                for varBinds in varBindTable:
                    key, val = varBinds
                    if not val:
                        continue
                    mac = key.getMibSymbol()[-1][1].prettyPrint()
                    interface = str(int(val))
                    ports.setdefault(interface, []).append(mac)

        return ports
Ejemplo n.º 16
0
def construct_value_pairs(list_of_pairs):
    pairs = []

    for key, value in list_of_pairs.items():
        pairs.append(hlapi.ObjectType(hlapi.ObjectIdentity(key), value))

    return pairs
Ejemplo n.º 17
0
def construct_object_types(list_of_oids):
    object_types = []

    for oid in list_of_oids:
        object_types.append(hlapi.ObjectType(hlapi.ObjectIdentity(oid)))

    return object_types
Ejemplo n.º 18
0
        def get_table_symbols(mib, table):
            key = (mib, table)
            if key in table_oids:
                return table_oids[key][1]

            table_object = hlapi.ObjectType(hlapi.ObjectIdentity(mib, table))
            symbols = []
            table_oids[key] = (table_object, symbols)
            return symbols
Ejemplo n.º 19
0
def find_router_type(host, port):
    oid = '.1.3.6.1.2.1.1.1.0'
    #import pysnmp.hlapi as ph
    g = ph.getCmd(
        ph.SnmpEngine(), ph.CommunityData('otauB9v1kYRO'),
        ph.UdpTransportTarget((host, port)), ph.ContextData(),
        ph.ObjectType(ph.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
    nextg = next(g)
    print(nextg)
Ejemplo n.º 20
0
def construct_object_types_from_named_oid(list_of_oid_name_tuplets):
    object_types = []
    for oid in list_of_oid_name_tuplets:
        addr = []
        for x in oid:
            addr.append(x)
        object_types.append(
            hlapi.ObjectType(hlapi.ObjectIdentity(*addr).addMibSource('.')))
    return object_types
Ejemplo n.º 21
0
 def fetch_sysobject_oid(self, config):
     """Return the sysObjectID of the instance."""
     # Reference sysObjectID directly, see http://oidref.com/1.3.6.1.2.1.1.2
     oid = hlapi.ObjectType(hlapi.ObjectIdentity((1, 3, 6, 1, 2, 1, 1, 2)))
     self.log.debug('Running SNMP command on OID %r', oid)
     error_indication, _, _, var_binds = next(config.call_cmd(hlapi.nextCmd, oid, lookupMib=False))
     self.raise_on_error_indication(error_indication, config.ip_address)
     self.log.debug('Returned vars: %s', var_binds)
     return var_binds[0][1].prettyPrint()
Ejemplo n.º 22
0
        def get_table_symbols(mib, table):
            identity, table = extract_symbol(mib, table)
            key = (mib, table)
            if key in table_oids:
                return table_oids[key][1], table

            table_object = hlapi.ObjectType(identity)
            symbols = []
            table_oids[key] = (table_object, symbols)
            return symbols, table
Ejemplo n.º 23
0
def common():
    """PySNMP Tutorial Common Operations Example"""
    engine = hlapi.SnmpEngine()
    community = hlapi.CommunityData("public", mpModel=1)  # SNMPv2c
    target = hlapi.UdpTransportTarget(("192.168.0.59", 161))
    context = hlapi.ContextData()

    # object_id = hlapi.ObjectIdentity(
    #     "iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0"
    # )
    sysDescr = hlapi.ObjectType(
        hlapi.ObjectIdentity("SNMPv2-MIB", "sysDescr", 0))
    sysUpTime = hlapi.ObjectType(
        hlapi.ObjectIdentity("SNMPv2-MIB", "sysUpTime", 0))
    ifInOctets = hlapi.ObjectType(
        hlapi.ObjectIdentity("IF-MIB", "ifInOctets", 1))
    command = hlapi.getCmd(engine, community, target, context, sysDescr,
                           sysUpTime, ifInOctets)
    _old_print_results(command)
Ejemplo n.º 24
0
 def set(self, oid, value):
     identify = hlapi.ObjectType(hlapi.ObjectIdentity(oid),
                                 hlapi.Integer(value))
     g = hlapi.setCmd(self.engine,
                      self.community,
                      self.transport,
                      self.context,
                      identify,
                      lookupMib=False)
     next(g)
Ejemplo n.º 25
0
def set_one(target,
            oid,
            value,
            credentials,
            port=161,
            engine=hlapi.SnmpEngine(),
            context=hlapi.ContextData()):
    handler = hlapi.setCmd(engine, credentials,
                           hlapi.UdpTransportTarget((target, port)), context,
                           hlapi.ObjectType(hlapi.ObjectIdentity(oid), value))
    return fetch(handler, 1)[0]
Ejemplo n.º 26
0
 def get_by_oid(self, oid):
     res = hlapi.getCmd(
         hlapi.SnmpEngine(),
         self.auth_data,
         hlapi.UdpTransportTarget(self.target),
         hlapi.ContextData(),
         hlapi.ObjectType(hlapi.ObjectIdentity(oid)),
     )
     res = next(res)
     err_indication, err_status, err_index, var_binds = res
     return var_binds[0]
Ejemplo n.º 27
0
    def _construct_object_types(self, list_of_oids):  #oid 실제 구별할 값 찾기
        object_types = []
        for oid in list_of_oids:
            try:
                object_types.append(hlapi.ObjectType(
                    hlapi.ObjectIdentity(oid)))
            except Exception as e:
                print('> _construct_object_types : ', e)
                traceback.print_exc(file=sys.stdout)
                continue

        return object_types
Ejemplo n.º 28
0
def construct_object_types(list_of_oids):
    """
    Build a SNMP payload object from oids for get requests
    inputs:
        list_of_oids (list(str))
    outputs:
        SNMP payload for Get requests
    """
    object_types = []
    for oid in list_of_oids:
        object_types.append(hlapi.ObjectType(hlapi.ObjectIdentity(oid).addMibSource('./mibs')))
    return object_types
Ejemplo n.º 29
0
    def get(self, oid):
        g = hlapi.getCmd(self.engine,
                         self.community,
                         self.transport,
                         self.context,
                         hlapi.ObjectType(hlapi.ObjectIdentity(oid)),
                         lookupMib=False)

        error_indication, error_status, _, res = next(g)
        if error_indication or error_status:
            raise ExecutionError("Failed to get SNMP value")
        return res[0][1]
Ejemplo n.º 30
0
    def get_by_var(self, mib_name, var_name, position=None):
        oid = ((mib_name, var_name) if position is None else
               (mib_name, var_name, position))

        res = hlapi.getCmd(
            hlapi.SnmpEngine(),
            self.auth_data,
            hlapi.UdpTransportTarget(self.target),
            hlapi.ContextData(),
            hlapi.ObjectType(hlapi.ObjectIdentity(*oid)),
        )
        res = next(res)
        err_indication, err_status, err_index, var_binds = res
        return var_binds[0]