示例#1
0
    def get_cbQosPoliceCfgTable(self, cbQosPoliceCfgEntries):

        self.logger.debug("in get_cbQosPoliceCfgTable")
        cbQosPoliceCfgTable = autovivification.AutoVivification()
        for cbQosPoliceCfgEntry in list(cbQosPoliceCfgEntries.keys()):
            array = cbQosPoliceCfgEntry.split('.')
            pName = array[13]
            cbQosConfigIndex = array[14]
            pVal = self.cbQosPoliceCfgEntry_lookup.get(pName, pName)
            cbQosPoliceCfgTable[cbQosConfigIndex][pVal] = cbQosPoliceCfgEntries[cbQosPoliceCfgEntry]

        return cbQosPoliceCfgTable
示例#2
0
    def collect(self,
                m,
                devicename='localhost'):
        """Create a new QOS collector.

            :param devicename: The hostname or IP address of the agent to
                connect to. Optionally, the port can be specified
                separated with a double colon.
            :type host: str
        """

        # start by collecting all relevant OID tables from the device.
        collection_start = datetime.now()

        # get cbQosServicePolicyEntries and format it in cbQosServicePolicyTable
        self.logger.info('get_table for cbQosServicePolicyEntry')
        cbQosServicePolicyEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosServicePolicyEntry'))
        cbQosServicePolicyTable = self.get_cbQosServicePolicyTable(cbQosServicePolicyEntries)

        # get ifDescr
        self.logger.info('get_table for ifDescr')
        ifEntries = self.get_table(m, devicename, self.node_to_oid('IF-MIB', 'ifDescr'))
        ifEntriesTable = self.get_ifEntriesTable(ifEntries)

        # get cbQosObjectsEntries
        self.logger.info('get_table for cbQosObjectsEntry')
        cbQosObjectsEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosObjectsEntry'))
        cbQosObjectsTable = self.get_cbQosObjectTable(cbQosObjectsEntries)

        # get cbQosPolicyMapCfgEntry
        self.logger.info('get_table for cbQosPolicyMapCfgEntry')
        cbQosPolicyMapCfgEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosPolicyMapCfgEntry'))
        cbQosPolicyMapCfgTable = self.get_cbQosPolicyMapTable(cbQosPolicyMapCfgEntries)

        # get cbQosCMCfgEntry
        self.logger.info('get_table for cbQosCMCfgEntry')
        cbQosCMCfgEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosCMCfgEntry'))
        cbQosCMCfgTable = self.get_cbQosCMCfgTable(cbQosCMCfgEntries)

        # get cbQosQueueingCfgEntry
        self.logger.info('get_table for cbQosQueueingCfgEntry')
        cbQosQueueingCfgEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosQueueingCfgEntry'))
        cbQosQueueingCfgTable = self.get_cbQosQueueingCfgTable(cbQosQueueingCfgEntries)

        # get cbQosTSCfgEntry (shaping config)
        self.logger.info('get_table for cbQosTSCfgEntry')
        cbQosTSCfgEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosTSCfgEntry'))
        cbQosTSCfgTable = self.get_cbQosTSCfgTable(cbQosTSCfgEntries)

        # get cbQosPoliceCfgEntry
        self.logger.info('get_table for cbQosPoliceCfgEntry')
        cbQosPoliceCfgEntries = self.get_table(m, devicename, self.node_to_oid('CISCO-CLASS-BASED-QOS-MIB', 'cbQosPoliceCfgEntry'))
        cbQosPoliceCfgTable = self.get_cbQosPoliceCfgTable(cbQosPoliceCfgEntries)

        collection_end = datetime.now()
        tdiff = collection_end - collection_start
        collection_duration = (tdiff.microseconds + (tdiff.seconds + tdiff.days * 24 * 3600) * 10 ** 6) / 1000
        analysis_start = datetime.now()

        # ---------------------------------------------------------------------------------------
        # construct list of interfaces having QoS defined
        # use a dict so we get auto-unification
        # ---------------------------------------------------------------------------------------
        self.logger.info("get table of interfaces with QoS")
        interfaces = {}
        for cbQosPolicyIndex in list(cbQosServicePolicyTable.keys()):
            qos_interface_idx = cbQosServicePolicyTable[cbQosPolicyIndex]['cbQosIfIndex']
            # only for real interfaces, see InterfaceType in CISCO-CLASS-BASED-QOS-MIB for other values
            qos_interface_type = cbQosServicePolicyTable[cbQosPolicyIndex]['cbQosIfType']
            if qos_interface_type == "1":
                interface_name = ifEntriesTable.get(qos_interface_idx, 'noNameInterface')
                interfaces[qos_interface_idx] = interface_name
            else:
                self.logger.info('skipped interface idx %s because its type is %s' % (qos_interface_idx, qos_interface_type))

        # ---------------------------------------------------------------------------------------
        # prepare an interface table object to make later parsing easier
        #
        # each entry in InterfacesTable is built as:
        #    key   -> interface-name
        #    value -> array of service-policies indices
        #    eg    'GigabitEthernet0/0' -> [16, 18]
        #          'GigabitEthernet0/2' -> [50]
        #
        # two rounds to build the table, first the key->table, then fill each table
        # ---------------------------------------------------------------------------------------
        InterfacesTable = {}
        for idx in cbQosServicePolicyTable:
            (interface_idx, interface_name) = self.get_interface(idx, cbQosServicePolicyTable, interfaces)
            self.logger.debug('InterfacesTable list build : name = <%s>' % (interface_name))
            if interface_name:
                InterfacesTable[interface_name] = []
        for idx in cbQosServicePolicyTable:
            (interface_idx, interface_name) = self.get_interface(idx, cbQosServicePolicyTable, interfaces)
            if interface_name:
                InterfacesTable[interface_name].append(idx)

        # loop over the cbQosObjectsTable to build its hierarchy
        # ---------------------------------------------------------------------------------------
        self.logger.info("build the hierarchy of cbQosObjectsTable in ObjectsTable")

        ObjectsTable = autovivification.AutoVivification()

        for cbQosObjectsTable_top_idx in list(cbQosObjectsTable.keys()):

            # store the interface name
            (interface_idx, interface_name) = self.get_interface(cbQosObjectsTable_top_idx, cbQosServicePolicyTable,
                                                            interfaces)
            ObjectsTable[cbQosObjectsTable_top_idx]['ifname'] = interface_name

            # first, find the top-level policy-maps attached to interfaces, aka service-policies
            indices_L1 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx, self.object_types['policymap'], '0')
            for idx_L1 in indices_L1:
                cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L1, cbQosObjectsTable)
                policymapname = self.get_policymap_name(cbQosConfigIndex, cbQosPolicyMapCfgTable)
                policymapdirection = self.policy_traffic_direction_names[
                    self.get_policymap_direction(cbQosObjectsTable_top_idx, cbQosServicePolicyTable)]
                ObjectsTable[cbQosObjectsTable_top_idx]['servicePolicyName'] = policymapname
                ObjectsTable[cbQosObjectsTable_top_idx]['servicePolicyDirection'] = policymapdirection
                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'] = {}

                # second, find the class-maps within the current service-policy
                indices_L2 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx, self.object_types['classmap'], idx_L1)
                for idx_L2 in indices_L2:
                    cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L2, cbQosObjectsTable)
                    classmapname_L2 = self.get_classmap_name(cbQosConfigIndex, cbQosCMCfgTable)
                    ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2] = {}

                    # find the bandwidth info for this class-map
                    indices_L2b = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx, self.object_types['queueing'],
                                              idx_L2)
                    for idx_L2b in indices_L2b:
                        cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L2b, cbQosObjectsTable)
                        (bandwidth, units) = self.get_bandwidth(cbQosConfigIndex, cbQosQueueingCfgTable)
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['cfgidx'] = idx_L2
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['idx_L2'] = idx_L2
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['bw'] = bandwidth
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['bw_unit'] = units
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['bw_unit_text'] = \
                        self.queueing_bandwidth_units[units]

                    # find the police info for this class-map
                    indices_L2b = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx, self.object_types['police'],
                                              idx_L2)
                    for idx_L2b in indices_L2b:
                        cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L2b, cbQosObjectsTable)
                        (police_rate, police_rate_type, police_percent_rate) = self.get_police(cbQosConfigIndex, cbQosPoliceCfgTable)
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['cfgidx'] = idx_L2
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['idx_L2'] = idx_L2
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'police_rate'] = police_rate
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'police_rate_type'] = police_rate_type
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'police_rate_type_text'] = self.police_rate_types[police_rate_type]
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'police_percent_rate'] = police_percent_rate

                    # find the shaping info for this class-map
                    indices_L2b = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx,
                                                   self.object_types['trafficShaping'], idx_L2)
                    for idx_L2b in indices_L2b:
                        cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L2b, cbQosObjectsTable)
                        (shape_rate, shape_type) = self.get_shaping(cbQosConfigIndex, cbQosTSCfgTable)
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['cfgidx'] = idx_L2
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'shape_rate'] = shape_rate
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'shape_type'] = shape_type
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['shape_type_text'] = \
                        self.shaping_rate_types[shape_type]

                    # find the random-detect info for this class-map
                    indices_L2b = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx,
                                                   self.object_types['randomDetect'], idx_L2)
                    for idx_L2b in indices_L2b:
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['cfgidx'] = idx_L2
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['random_detect'] = True

                    # third level : the policy-maps within the current class-map
                    indices_L3 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx, self.object_types['policymap'],
                                             idx_L2)
                    for idx_L3 in indices_L3:
                        cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L3, cbQosObjectsTable)
                        policymapname_L3 = self.get_policymap_name(cbQosConfigIndex, cbQosPolicyMapCfgTable)
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2][
                            'PolicyName'] = policymapname_L3
                        ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'] = {}

                        # fourth level : the class-maps within the current policy-map
                        indices_L4 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx, self.object_types['classmap'],
                                                 idx_L3)
                        for idx_L4 in indices_L4:
                            cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L4,
                                                                    cbQosObjectsTable)
                            classmapname_L4 = self.get_classmap_name(cbQosConfigIndex, cbQosCMCfgTable)
                            ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                classmapname_L4] = {}

                            # find the bandwidth info for this class-map
                            indices_L5 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx,
                                                          self.object_types['queueing'], idx_L4)
                            for idx_L5 in indices_L5:
                                cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L5,
                                                                        cbQosObjectsTable)
                                (bandwidth, units) = self.get_bandwidth(cbQosConfigIndex, cbQosQueueingCfgTable)
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['cfgidx'] = idx_L4
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['bw'] = bandwidth
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['bw_unit'] = units
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['bw_unit_text'] = self.queueing_bandwidth_units[units]

                            # find the police info for this class-map
                            indices_L5 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx,
                                                          self.object_types['police'], idx_L4)
                            for idx_L5 in indices_L5:
                                cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L5,
                                                                        cbQosObjectsTable)
                                (police_rate, police_rate_type, police_percent_rate) = self.get_police(cbQosConfigIndex, cbQosPoliceCfgTable)
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['cfgidx'] = idx_L4
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['police_rate'] = police_rate
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['police_rate_type'] = police_rate_type
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['police_rate_type_text'] = self.police_rate_types[police_rate_type]
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['police_percent_rate'] = police_percent_rate

                            # find the shaping info for this class-map
                            indices_L5 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx,
                                                          self.object_types['trafficShaping'], idx_L4)
                            for idx_L5 in indices_L5:
                                cbQosConfigIndex = self.get_cbQosConfigIndex(cbQosObjectsTable_top_idx, idx_L5,
                                                                        cbQosObjectsTable)
                                (shape_rate, shape_type) = self.get_shaping(cbQosConfigIndex, cbQosTSCfgTable)
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['cfgidx'] = idx_L4
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['shape_rate'] = shape_rate
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['shape_type'] = shape_type
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['shape_type_text'] = self.shaping_rate_types[shape_type]

                            # find the random-detect info for this class-map
                            indices_L5 = self.get_indices(cbQosObjectsTable, cbQosObjectsTable_top_idx,
                                                          self.object_types['randomDetect'], idx_L4)
                            for idx_L5 in indices_L5:
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['cfgidx'] = idx_L4
                                ObjectsTable[cbQosObjectsTable_top_idx]['class-maps'][classmapname_L2]['class-maps'][
                                    classmapname_L4]['random_detect'] = True

                            # REMARK :
                            # we are now in double-nested classes :
                            # interface -> service-policy -> class-map -> policy-map -> class-map
                            # deeper recursion in QoS is indeed possible but improbable, so we stop recursing here.

        # ---------------------------------------------------------------------------------------
        # present the results
        # for each interface, we show the attached service-policy, then dig-down to the sub-objects
        # ---------------------------------------------------------------------------------------
        self.logger.info("consolidate the hierarchy to a JSON structure")

        # to collect everything related to QoS in a large JSON object
        qosinfo = autovivification.AutoVivification()

        for interface_idx in sorted(interfaces):

            # each interface
            interface_name = interfaces[interface_idx]
            self.logger.debug("presentation: working on interface <%s>" % interface_name)

            # for each service-policy bound to the current interface
            for ObjectsTable_idx in sorted(InterfacesTable[interface_name]):
                service_policy_name = ObjectsTable[ObjectsTable_idx]['servicePolicyName']
                qosinfo[interface_name]['service-policies'][service_policy_name]['direction'] = \
                ObjectsTable[ObjectsTable_idx]['servicePolicyDirection']

                # second, find the class-maps within the current service-policy
                for class_map_L1 in sorted(ObjectsTable[ObjectsTable_idx]['class-maps']):

                    # policing : either percentage or rate
                    if 'police_rate_type' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]:
                        if ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['police_rate_type'] == '2':
                            qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                class_map_L1]['police_rate'] = "%s %s" % (
                            ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['police_percent_rate'],
                            ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['police_rate_type_text'])
                        else:
                            qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                class_map_L1]['police_rate'] = "%s %s" % (
                            ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['police_rate'],
                            ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['police_rate_type_text'])

                    # bandwitdh
                    if 'bw' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]:
                        qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][class_map_L1][
                            'bandwidth'] = "%s %s" % (ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['bw'],
                                                      ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1][
                                                          'bw_unit_text'])

                    # the shaping
                    if 'shape_rate' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]:
                        qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][class_map_L1][
                            'shape_rate'] = "%s %s" % (
                        self.format_nr(ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['shape_rate']),
                        ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['shape_type_text'])

                    # in case someone wants to graph something, here is how you get the OIDs
                    if 'cfgidx' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]:
                        obj_idx = ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['cfgidx']
                        cbQosCMPostPolicyByte64_oid = self.get_full_oid('cbQosCMPostPolicyByte64', ObjectsTable_idx, obj_idx)
                        cbQosCMDropPkt64_oid = self.get_full_oid('cbQosCMDropPkt64', ObjectsTable_idx, obj_idx)
                        qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][class_map_L1][
                            'oids']['cbQosCMPostPolicyByte64'] = cbQosCMPostPolicyByte64_oid
                        qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][class_map_L1][
                            'oids']['cbQosCMDropPkt64'] = cbQosCMDropPkt64_oid

                    # third level : the policy-maps within the current L1-class-map
                    if 'PolicyName' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]:
                        policy_map_name = ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['PolicyName']

                    # each class-map
                    if 'class-maps' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]:
                        for class_map_L2 in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps']:

                            # bandwidth
                            if 'bw' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                class_map_L2]:
                                qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                    class_map_L1]['policy-maps'][policy_map_name]['class-maps'][class_map_L2][
                                    'bandwidth'] = "%s %s" % (
                                ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][class_map_L2][
                                    'bw'],
                                ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][class_map_L2][
                                    'bw_unit_text'])

                            # policing : either percentage or rate
                            if 'police_rate_type' in \
                                    ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                        class_map_L2]:
                                if \
                                ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][class_map_L2][
                                    'police_rate_type'] == '2':
                                    qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                        class_map_L1]['policy-maps'][policy_map_name]['class-maps'][
                                        class_map_L2]['police_rate'] = "%s %s" % (
                                        ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                            class_map_L2][
                                            'police_percent_rate'],
                                        ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                            class_map_L2][
                                            'police_rate_type_text'])
                                else:
                                    qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                        class_map_L1]['policy-maps'][policy_map_name]['class-maps'][class_map_L2][
                                        'police_rate'] = "%s %s" % (
                                        ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                            class_map_L2]['police_rate'],
                                        ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                            class_map_L2]['police_rate_type_text'])

                            # shaping
                            if 'shape_rate' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                class_map_L2]:
                                qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                    class_map_L1]['policy-maps'][policy_map_name]['class-maps'][class_map_L2][
                                    'shape_rate'] = "%s %s" % (self.format_nr(
                                    ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                        class_map_L2]['shape_rate']), ObjectsTable[ObjectsTable_idx]['class-maps'][
                                                                   class_map_L1]['class-maps'][class_map_L2][
                                                                   'shape_type_text'])

                            # in case someone wants to graph something, here is how you get the OIDs
                            if 'cfgidx' in ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][
                                class_map_L2]:
                                obj_idx = \
                                ObjectsTable[ObjectsTable_idx]['class-maps'][class_map_L1]['class-maps'][class_map_L2][
                                    'cfgidx']
                                cbQosCMPostPolicyByte64_oid = self.get_full_oid('cbQosCMPostPolicyByte64', ObjectsTable_idx,
                                                                           obj_idx)
                                cbQosCMDropPkt64_oid = self.get_full_oid('cbQosCMDropPkt64', ObjectsTable_idx, obj_idx)
                                qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                    class_map_L1]['policy-maps'][policy_map_name]['class-maps'][class_map_L2]['oids'][
                                    'cbQosCMPostPolicyByte64'] = cbQosCMPostPolicyByte64_oid
                                qosinfo[interface_name]['service-policies'][service_policy_name]['class-maps'][
                                    class_map_L1]['policy-maps'][policy_map_name]['class-maps'][class_map_L2]['oids'][
                                    'cbQosCMDropPkt64'] = cbQosCMDropPkt64_oid

        analysis_end = datetime.now()
        tdiff = analysis_end - analysis_start
        analysis_duration = (tdiff.microseconds + (tdiff.seconds + tdiff.days * 24 * 3600) * 10 ** 6) / 1000

        self.logger.info('collection_duration=%s, analysis_duration=%s' % (collection_duration, analysis_duration))

        # add all the stuff to a data structure and encode in JSON

        meta = {}
        meta['timestamp'] = datetime.now().isoformat()
        meta['collection_duration'] = collection_duration
        meta['devicename'] = devicename
        meta['interfaces_count'] = len(qosinfo)

        self.logger.debug('fn=QOS/collect : %s : returning qos info for %s interfaces' % (devicename, len(qosinfo)))
        return meta, qosinfo