Beispiel #1
0
    def _bulkwalk(self, oids, keys=None, index=None, num_base_nodes=0, ret_raw=False, orderby=None, is_hex=False,
                  to_str=True, proc=None, bulk_size=None, timeout=None):
        '''
        :param oids: dict
        :param keys: 替换snmp oid为字符串
            {'1': 'xxx', '2': 'yyy'}
        :param index:   数字, 返回dict, 以index为key, 会忽略空值

        :param num_base_nodes:
        :param ret_raw: 返回迭代器, 因为有时需要详细的oid, 但tablify返回不带oid
            for row in raw:
                print('%s: %r' % row)
        :param orderby: 排序
        :param to_str: 返回str,否则可能转成int或float
        :param proc: (func, *args), 不使用tablify,proc, 返回(key, value)组成字典
        :param timeout: puresnmp的bulkwalk有bug,不能传递timeout
        :return:
        '''
        # 一些puresnmp版本中bulkwalk不包含timeout,需要检查
        d = {'timeout': timeout or self.timeoout} if 'timeout' in getfullargspec(bulkwalk).args else {}
        raw = bulkwalk(oids=oids.keys(), bulk_size=bulk_size or self.bulk_size, **d, **self.snmp_auth)
        if proc:
            func, *args = proc
            d = OrderedDict()
            for x in raw:
                k, v = func(x, *args)
                d[k] = v
            return d
        if ret_raw:
            # [(k, bytes_decode(v, to_type=to_type)) for k, v in raw]
            return raw
        lst = tablify(raw, num_base_nodes=num_base_nodes)
        if orderby:
            if isinstance(orderby, str):
                lst.sort(key=lambda x: x[orderby])
            elif hasattr(orderby, '__call__'):
                lst.sort(key=orderby)
        if keys:
            if '0' not in keys:
                keys['0'] = 'id'
            _lst = []
            for i, x in enumerate(lst):
                d = {keys.get(k, k): bytes_decode(x[k], to_type='str' if to_str else None, is_hex=is_hex) for k, v in
                     x.items()}
                _lst.append(d)
            if not index or index not in keys:
                return _lst
            _dict = OrderedDict()
            _index = keys[index]
            for i, x in enumerate(_lst):
                if not x[_index]:
                    continue
                _dict[x[_index]] = x
            return _dict
        else:
            return [{k: bytes_decode(v, to_type='str' if to_str else None) for k, v in x.items()} for i, x in
                    enumerate(lst)]
Beispiel #2
0
    def test_get_call_args(self):
        data = readbytes('dummy.hex')  # any dump would do
        packet = Sequence(Integer(Version.V2C), OctetString('public'),
                          BulkGetRequest(0, 0, 2, ObjectIdentifier(1, 2, 3)))
        with patch('puresnmp.send') as mck, \
                patch('puresnmp.get_request_id') as mck2:
            mck2.return_value = 0
            mck.return_value = data

            # we need to wrap this in a list to consume the generator.
            list(bulkwalk('::1', 'public', ['1.2.3'], bulk_size=2))
            mck.assert_called_with('::1', 161, bytes(packet), timeout=2)
    def test_get_call_args_issue_22(self):
        data = readbytes('dummy.hex')  # any dump would do
        packet = Sequence(Integer(Version.V2C), OctetString('public'),
                          BulkGetRequest(0, 0, 2, ObjectIdentifier(1, 2, 3)))
        with patch('puresnmp.send') as mck, \
                patch('puresnmp.get_request_id') as mck2:
            mck2.return_value = 0
            mck.return_value = data

            with self.assertRaisesRegex(TypeError, 'OIDS.*list'):
                # we need to wrap this in a list to consume the generator.
                list(bulkwalk('::1', 'public', '1.2.3', bulk_size=2))
Beispiel #4
0
    def fdb(self, vlanrange):
        swNumber = int(self.ipaddress.rpartition('.')[2])
        if self.vendor == 'cisco':
            def portnumber(interfacename, quantity):
                if interfacename[0] == 'F':
                    return int(interfacename.rpartition('/')[2])
                elif interfacename[0] == 'G':
                    return int(interfacename.rpartition('/')[2])+quantity

            dot1dTpFdbPort = ['.1.3.6.1.2.1.17.4.3.1.2']
            dot1dBasePortIfIndex = ['.1.3.6.1.2.1.17.1.4.1.2']
            vtpVlanState = ['.1.3.6.1.4.1.9.9.46.1.3.1.1.2.1']
            oidifName = ['.1.3.6.1.2.1.31.1.1.1.1']
            swIfaces = bulkwalk(self.ipaddress, self.community, oidifName)
            swVlans = set(int(vlan.oid[-1]) for vlan in bulkwalk(
                self.ipaddress, self.community, vtpVlanState)) & set(vlanrange)
            swIfNames = {int(i.oid[-1]): i.value.decode('utf-8') for i in swIfaces}
            swMappings = {
                int(m.oid[-1]): swIfNames[int(m.value)]
                for v in swVlans
                for m in bulkwalk(self.ipaddress, "@".join([self.community, str(v)]), dot1dBasePortIfIndex)}
            swFDB = (
                (swNumber, portnumber(swMappings[m.value], 48), ":".join(
                    ["{:02X}".format(int(octet)) for octet in m.oid[-6:]]), v) for v in swVlans for m in bulkwalk(
                    self.ipaddress, "@".join(
                        [self.community, str(v)]), dot1dTpFdbPort) if swMappings[m.value] not in self.uplinkports)
            return swFDB
        elif self.vendor == 'dlink':
            oiddot1qTpFdbEntry = ['.1.3.6.1.2.1.17.7.1.2.2.1.2']
            swFDB = (
                (swNumber, int(m.value), ":".join(
                    ["{:02X}".format(int(octet)) for octet in m.oid[-6:]]), int(m.oid[-7]))
                for m in bulkwalk(self.ipaddress, self.community, oiddot1qTpFdbEntry)
                if int(m.oid[-7]) in vlanrange if str(m.value) not in self.uplinkports)
            return swFDB
        else:
            return None
Beispiel #5
0
    def test_bulkwalk(self):
        response = readbytes_multiple('apiv1/bulkwalk_response.hex')
        self.transport.send.side_effect = response
        result = list(snmp.bulkwalk('192.168.1.1', 'private', [
            '1.3.6.1.2.1.1.9.1.4']))

        expected = [
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.1'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.2'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.3'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.4'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.5'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.6'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.7'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.8'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.9'), datetime.timedelta(0)),
            VarBind(OID('1.3.6.1.2.1.1.9.1.4.10'), datetime.timedelta(0))
        ]

        self.assertEqual(result, expected)
        self.assertTrue(self.transport.send.called, 'method was not called')
        expected_types = [(ObjectIdentifier, datetime.timedelta)] * 10
        returned_values = [(row.oid, row.value) for row in result]
        assert_of_types(returned_values, expected_types)
Beispiel #6
0
    def __process_methods(method, common_parameters, datatype_config):
        response = None

        if method == "get":
            oid = datatype_config["oid"]
            response = puresnmp.get(**common_parameters, oid=oid)
        elif method == "multiget":
            oids = datatype_config["oid"]
            oids = oids if isinstance(oids, list) else list(oids)
            response = puresnmp.multiget(**common_parameters, oids=oids)
        elif method == "getnext":
            oid = datatype_config["oid"]
            master_response = puresnmp.getnext(**common_parameters, oid=oid)
            response = {master_response.oid: master_response.value}
        elif method == "multigetnext":
            oids = datatype_config["oid"]
            oids = oids if isinstance(oids, list) else list(oids)
            master_response = puresnmp.multigetnext(**common_parameters,
                                                    oids=oids)
            response = {
                binded_var.oid: binded_var.value
                for binded_var in master_response
            }
        elif method == "walk":
            oid = datatype_config["oid"]
            response = {
                binded_var.oid: binded_var.value
                for binded_var in list(
                    puresnmp.walk(**common_parameters, oid=oid))
            }
        elif method == "multiwalk":
            oids = datatype_config["oid"]
            oids = oids if isinstance(oids, list) else list(oids)
            response = {
                binded_var.oid: binded_var.value
                for binded_var in list(
                    puresnmp.multiwalk(**common_parameters, oids=oids))
            }
        elif method == "set":
            oid = datatype_config["oid"]
            value = datatype_config["value"]
            response = puresnmp.set(**common_parameters, oid=oid, value=value)
        elif method == "multiset":
            mappings = datatype_config["mappings"]
            response = puresnmp.multiset(**common_parameters,
                                         mappings=mappings)
        elif method == "bulkget":
            scalar_oids = datatype_config.get("scalarOid", [])
            scalar_oids = scalar_oids if isinstance(
                scalar_oids, list) else list(scalar_oids)
            repeating_oids = datatype_config.get("repeatingOid", [])
            repeating_oids = repeating_oids if isinstance(
                repeating_oids, list) else list(repeating_oids)
            max_list_size = datatype_config.get("maxListSize", 1)
            response = puresnmp.bulkget(**common_parameters,
                                        scalar_oids=scalar_oids,
                                        repeating_oids=repeating_oids,
                                        max_list_size=max_list_size)._asdict()
        elif method == "bulkwalk":
            oids = datatype_config["oid"]
            oids = oids if isinstance(oids, list) else list(oids)
            bulk_size = datatype_config.get("bulkSize", 10)
            response = {
                binded_var.oid: binded_var.value
                for binded_var in list(
                    puresnmp.bulkwalk(
                        **common_parameters, bulk_size=bulk_size, oids=oids))
            }
        elif method == "table":
            oid = datatype_config["oid"]
            del common_parameters["timeout"]
            num_base_nodes = datatype_config.get("numBaseNodes", 0)
            response = puresnmp.table(**common_parameters,
                                      oid=oid,
                                      num_base_nodes=num_base_nodes)
        elif method == "bulktable":
            oid = datatype_config["oid"]
            num_base_nodes = datatype_config.get("numBaseNodes", 0)
            bulk_size = datatype_config.get("bulkSize", 10)
            response = puresnmp.bulktable(**common_parameters,
                                          oid=oid,
                                          num_base_nodes=num_base_nodes,
                                          bulk_size=bulk_size)
        else:
            log.error("Method \"%s\" - Not found", str(method))
        return response
Beispiel #7
0
    def test_bulkwalk(self, mck_rid, mck_send):
        req1 = readbytes('bulkwalk_request_1.hex')
        req2 = readbytes('bulkwalk_request_2.hex')
        req3 = readbytes('bulkwalk_request_3.hex')

        responses = [
            readbytes('bulkwalk_response_1.hex'),
            readbytes('bulkwalk_response_2.hex'),
            readbytes('bulkwalk_response_3.hex'),
        ]
        mck_send.side_effect = responses

        request_ids = [1001613222, 1001613223, 1001613224]
        mck_rid.side_effect = request_ids

        result = list(
            bulkwalk('127.0.0.1', 'private', ['1.3.6.1.2.1.2.2'],
                     bulk_size=20))

        self.assertEqual(mck_send.mock_calls, [
            call('127.0.0.1', 161, req1, timeout=2),
            call('127.0.0.1', 161, req2, timeout=2),
            call('127.0.0.1', 161, req3, timeout=2),
        ])

        # TODO (advanced): Type information is lost for timeticks and OIDs
        expected = [
            VarBind('1.3.6.1.2.1.2.2.1.1.1', 1),
            VarBind('1.3.6.1.2.1.2.2.1.1.10', 10),
            VarBind('1.3.6.1.2.1.2.2.1.2.1', b"lo"),
            VarBind('1.3.6.1.2.1.2.2.1.2.10', b"eth0"),
            VarBind('1.3.6.1.2.1.2.2.1.3.1', 24),
            VarBind('1.3.6.1.2.1.2.2.1.3.10', 6),
            VarBind('1.3.6.1.2.1.2.2.1.4.1', 65536),
            VarBind('1.3.6.1.2.1.2.2.1.4.10', 1500),
            VarBind('1.3.6.1.2.1.2.2.1.5.1', 10000000),
            VarBind('1.3.6.1.2.1.2.2.1.5.10', 4294967295),
            VarBind('1.3.6.1.2.1.2.2.1.6.1', b""),
            VarBind('1.3.6.1.2.1.2.2.1.6.10', b"\x02\x42\xAC\x11\x00\x02"),
            VarBind('1.3.6.1.2.1.2.2.1.7.1', 1),
            VarBind('1.3.6.1.2.1.2.2.1.7.10', 1),
            VarBind('1.3.6.1.2.1.2.2.1.8.1', 1),
            VarBind('1.3.6.1.2.1.2.2.1.8.10', 1),
            VarBind('1.3.6.1.2.1.2.2.1.9.1', timedelta(0)),
            VarBind('1.3.6.1.2.1.2.2.1.9.10', timedelta(0)),
            VarBind('1.3.6.1.2.1.2.2.1.10.1', 172),
            VarBind('1.3.6.1.2.1.2.2.1.10.10', 60558),
            VarBind('1.3.6.1.2.1.2.2.1.11.1', 2),
            VarBind('1.3.6.1.2.1.2.2.1.11.10', 564),
            VarBind('1.3.6.1.2.1.2.2.1.12.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.12.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.13.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.13.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.14.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.14.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.15.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.15.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.16.1', 172),
            VarBind('1.3.6.1.2.1.2.2.1.16.10', 44295),
            VarBind('1.3.6.1.2.1.2.2.1.17.1', 2),
            VarBind('1.3.6.1.2.1.2.2.1.17.10', 442),
            VarBind('1.3.6.1.2.1.2.2.1.18.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.18.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.19.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.19.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.20.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.20.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.21.1', 0),
            VarBind('1.3.6.1.2.1.2.2.1.21.10', 0),
            VarBind('1.3.6.1.2.1.2.2.1.22.1',
                    '0.0'),  # TODO: type info is lost
            VarBind('1.3.6.1.2.1.2.2.1.22.10',
                    '0.0'),  # TODO: type info is lost
        ]

        # TODO: Expected types per OID:
        # 1.3.6.1.2.1.2.2.1.1.1 = INTEGER: 1
        # 1.3.6.1.2.1.2.2.1.1.10 = INTEGER: 10
        # 1.3.6.1.2.1.2.2.1.2.1 = STRING: "lo"
        # 1.3.6.1.2.1.2.2.1.2.10 = STRING: "eth0"
        # 1.3.6.1.2.1.2.2.1.3.1 = INTEGER: 24
        # 1.3.6.1.2.1.2.2.1.3.10 = INTEGER: 6
        # 1.3.6.1.2.1.2.2.1.4.1 = INTEGER: 65536
        # 1.3.6.1.2.1.2.2.1.4.10 = INTEGER: 1500
        # 1.3.6.1.2.1.2.2.1.5.1 = Gauge32: 10000000
        # 1.3.6.1.2.1.2.2.1.5.10 = Gauge32: 4294967295
        # 1.3.6.1.2.1.2.2.1.6.1 = ""
        # 1.3.6.1.2.1.2.2.1.6.10 = Hex-STRING: 02 42 AC 11 00 02
        # 1.3.6.1.2.1.2.2.1.7.1 = INTEGER: 1
        # 1.3.6.1.2.1.2.2.1.7.10 = INTEGER: 1
        # 1.3.6.1.2.1.2.2.1.8.1 = INTEGER: 1
        # 1.3.6.1.2.1.2.2.1.8.10 = INTEGER: 1
        # 1.3.6.1.2.1.2.2.1.9.1 = Timeticks: (0) 0:00:00.00
        # 1.3.6.1.2.1.2.2.1.9.10 = Timeticks: (0) 0:00:00.00
        # 1.3.6.1.2.1.2.2.1.10.1 = Counter32: 172
        # 1.3.6.1.2.1.2.2.1.10.10 = Counter32: 60558

        # 1.3.6.1.2.1.2.2.1.11.1 = Counter32: 2
        # 1.3.6.1.2.1.2.2.1.11.10 = Counter32: 564
        # 1.3.6.1.2.1.2.2.1.12.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.12.10 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.13.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.13.10 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.14.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.14.10 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.15.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.15.10 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.16.1 = Counter32: 172
        # 1.3.6.1.2.1.2.2.1.16.10 = Counter32: 44295
        # 1.3.6.1.2.1.2.2.1.17.1 = Counter32: 2
        # 1.3.6.1.2.1.2.2.1.17.10 = Counter32: 442
        # 1.3.6.1.2.1.2.2.1.18.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.18.10 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.19.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.19.10 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.20.1 = Counter32: 0
        # 1.3.6.1.2.1.2.2.1.20.10 = Counter32: 0

        # 1.3.6.1.2.1.2.2.1.21.1 = Gauge32: 0
        # 1.3.6.1.2.1.2.2.1.21.10 = Gauge32: 0
        # 1.3.6.1.2.1.2.2.1.22.1 = OID: ccitt.0
        # 1.3.6.1.2.1.2.2.1.22.10 = OID: ccitt.0
        self.assertEqual(result, expected)