Ejemplo n.º 1
0
    def sysDetails(self):
        basePath = self.cmcPolicyRetarget('/rbt/sport/sysdetail/state')
        fields = self.fields
        appliance = fields.get('appliance')

        if appliance:
            # Get the data from the appliance directly.
            data = self.mgmt.action(
                    '/cmc/actions/appliance/query',
                    ('appliance', 'string', appliance),
                    ('operation', 'string', 'iterate'),
                    ('flags', 'string', 'subtree'),
                    ('timeout', 'uint32', '30'),
                    ('node', 'string', basePath))

            # Pop off the basePath from the keys so we can treeify correctly.
            for k in data.keys():
                v = data.pop(k)
                if k.startswith(basePath):
                    k = k[len(basePath):]
                    if k.startswith("/"):
                        k = k[1:]
                    if k:
                        data[k] = v

            data = Nodes.treeifySubtree(data);
        else:
            data = Nodes.getTreeifiedSubtree(self.mgmt, basePath);

        # if sport is not running there won't be a 'sport' subtree so
        # use an empty dict instead
        sportModules = data.get('sport') or {}
        systemModules = data.get('system') or {}

        result = self.doc.createElement('systemDetails')

        # Maps to a 'status_map' enum in the backend:
        #     products/rbt_sh/src/bin/cli/modules/python/cli_rbt_sysdetail_cmds.py
        prettyStatuses = ['OK', 'Warning', 'Error', 'Disabled']

        # Takes in a system details data dict and adds each entry as an
        # attribute to the XML element in a pretty way.
        # moduleEl - an XML element
        # moduleName - the name the system module. Due to the design
        #                     of the backend, this attribute is not included
        #                     in moduleData dict.
        # moduleData - a data dict with entries that become XML attributes.
        def parseDataAndAttributizeXml(moduleEl, moduleName, moduleData):
            moduleEl.setAttribute('name', moduleName)

            # Formatting module data by replacing newlines with semicolons.
            # Semicolons get converted to newlines in JS.
            info = moduleData.get('info', '').replace('\n', ';')

            # Strip the last newline from info output (this fixes the bug where
            # an extra <br /> would show up at the end of each module info div)
            if info[-1:] == ';':
                info = info[:-1]

            if not info: # If no details, insert "<None>" message.
                info = "No details."
            moduleEl.setAttribute('info', info)

            statusMsg = prettyStatuses[int(moduleData.get('status', '2'))]
            moduleEl.setAttribute('status', statusMsg)
            moduleEl.setAttribute('statusTdClass', statusMsg.lower())

            return moduleEl

        # Sort module names to maintain display order.
        sysModuleNames = systemModules.keys()
        sysModuleNames.sort(FormUtils.alphanumericCompare)
        sportModuleNames = sportModules.keys()
        sportModuleNames.sort(FormUtils.alphanumericCompare)
        sortedModuleNames = sysModuleNames + sportModuleNames

        for moduleName in sortedModuleNames:
            if moduleName in sysModuleNames:
                moduleData = systemModules.get(moduleName)
            else:
                moduleData = sportModules.get(moduleName)

            moduleEl = self.doc.createElement('module')
            moduleEl = parseDataAndAttributizeXml(moduleEl,
                                                  moduleName,
                                                  moduleData)

            # Display additional submodules
            if 'items' in moduleData:
                submodules = moduleData.get('items')
                submoduleNames = submodules.keys()
                submoduleNames.sort(FormUtils.alphanumericCompare)

                # Loop through each submodule and add each entry as a child to
                # the module XML node
                for subName in submoduleNames:
                    subData = submodules.get(subName)
                    submoduleEl = self.doc.createElement('module')
                    prettyName = subData.get('name', '')

                    submoduleEl = parseDataAndAttributizeXml(submoduleEl,
                                                             prettyName,
                                                             subData)
                    moduleEl.appendChild(submoduleEl)

            result.appendChild(moduleEl)

        self.doc.documentElement.appendChild(result)
        self.writeXmlDoc()
Ejemplo n.º 2
0
    def netTestDetails(self):
        fields = self.request().fields()
        base = '/rbt/nettest/state/'
        table = self.getXmlTable(None, tagNames=('testDetails', 'testDetail'))

        testId = fields.get('id', '-1')
        assert int(testId) in self.netTestMap.values(), 'Invalid test specified.'

        testBasePath = base + testId # '/rbt/nettest/state/<testId>'

        # get all nodes under testBasePath
        if isCMC:
            app_prod, app_sn = self.fields.get('appliance').split('_')

            resp = self.mgmt.action(
                '/cmc/actions/appliance/query',
                ('appliance', 'string', app_sn),
                ('operation', 'string', 'iterate'),
                ('flags', 'string', 'subtree'),
                ('timeout', 'uint32', '120'),
                ('node', 'string', testBasePath))

            # take a dictionary of flat nodes and strip the base path off
            # the keys
            subtreeDict = {}
            for key, val in resp.iteritems():
                # strip /rbt/nettest/state/<testID>/
                subtreeDict[key[len(testBasePath) + 1:]] = val

            testSubtree = Nodes.treeifySubtree(subtreeDict)

        else:
            testSubtree = Nodes.getTreeifiedSubtree(self.mgmt, testBasePath)

        if 'attrib' in testSubtree:
            numRows = len(testSubtree['attrib'])
        else:
            numRows = 0

        aggregateResultDict = {}
        for row in xrange(numRows):
            res = testSubtree['result'][str(row)]
            if res in aggregateResultDict:
                aggregateResultDict[res] += 1
            else:
                aggregateResultDict[res] = 1

        # Parse run time output.
        hasRun = testSubtree['has_run']
        lastRun = testSubtree['last_run']
        lastRunPretty = ''
        if ('true' == hasRun):
            # expected time format to parse: "1970/01/01 13:59:59"
            format = '%Y/%m/%d %H:%M:%S'
            t = time.strptime(lastRun, format)
            # Two formats will work well here:
            # '%I:%M%p on %B %d, %Y' => "1:59PM on January 01, 1970"
            # '%Y/%m/%d %I:%M%p' => "1970/01/01 1:59PM"
            prettyFormat = '%I:%M%p on %B %d, %Y' # Use the former
            lastRunPretty = time.strftime(prettyFormat, t)

        table.open(self.request(),
                   id=testId,
                   name=testSubtree['name'],
                   has_run=hasRun,
                   run_state=self.netTestResultCodes[int(testSubtree['run_state'])],
                   last_run=lastRunPretty,
                   num_passed=aggregateResultDict.get('2', 0),
                   num_failed=aggregateResultDict.get('3', 0),
                   num_error=aggregateResultDict.get('4', 0),
                   num_undetermined=aggregateResultDict.get('5', 0))

        for row in xrange(numRows):
            cols = testSubtree['attrib'][str(row)]['value']

            # Create a list of arguments to pass to addEntry
            # {'attrib_0' : ../value/0,
            #  'attrib_1' : ../value/1,
            #  ...}
            args = {}
            for col in cols:
                attribName = 'attrib_' + str(col)
                args[attribName] = cols[col]

            # Results are returned from the backend as an enum value.
            returnCode = int(testSubtree['result'][str(row)])

            # Return the human-readable result code: 0 -> "Not Run", 3 -> "Error", etc
            args['result'] = self.netTestResultCodes[returnCode]

            # Equivalent to calling:
            # table.addEntry(attrib_0 = <value>, attrib_1 = <value>, ...)
            table.addEntry(**args)

        table.close()