⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 module.py

📁 监控大型网络的软件。能够自动发现拓扑结构
💻 PY
字号:
# -*- coding: UTF-8 -*-## Copyright 2002-2004 Norwegian University of Science and Technology# Copyright 2007 UNINETT AS## This file is part of Network Administration Visualized (NAV)## NAV is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## NAV is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with NAV; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA### Authors: Magnus Nordseth <magnun@itea.ntnu.no>#          Stian Soiland <stain@itea.ntnu.no>#          Stein Magnus Jodal <stein.magnus.jodal@uninett.no>#"""Presentation logic for switchport modules.Displays the module as a stack of ports, include simple port information(duplex, speed) in CSS style and for mouse hovering."""try:    from mod_python import apacheexcept:    passfrom nav.db import managefrom nav.web import urlbuilderfrom nav import utilimport forgetHTML as html#import warningsfrom sets import Setfrom datetime import datetime, timedelta# Color range for port activity tabcolor_recent = (116, 196, 118)color_longago = (229, 245, 224)# Active result set cache. Will live as long as the Apache child.active_cache = {}def process(request):    import netbox    netbox = netbox.findNetboxes(request['hostname'])    if len(netbox) > 1:        return    netbox=netbox[0]    module = findModule(netbox, request['module'])    request['templatePath'].append((str(netbox),                                    urlbuilder.createUrl(netbox)))    request['templatePath'].append(('Module %s' % module.module, None))    result = html.Division()    header = html.Header("Module %s at %s" %                         (module.module,                         urlbuilder.createLink(module.netbox)), level=2)    result.append(header)    perspectives = []    if netbox.cat.catid in ('GSW', 'SW', 'EDGE'):        perspectives.append(('Switch port status', 'standard'))        perspectives.append(('Switch port activity', 'active'))    if netbox.cat.catid in ('GW', 'GSW'):        perspectives.append(('Router port status', 'gwstandard'))    legends = []    for header, perspective in perspectives:        legends.append(perspective)    result.append(showModuleLegend(legends))    moduleInfo = ModuleInfo(module)    for header, perspective in perspectives:        module = moduleInfo.showModule(perspective)        if module:            result.append(html.Header(header, level=3))            result.append(module)    return resultdef findModule(netbox, moduleName):    moduleName = moduleName.replace("module", "")    try:        # Safe variable, must be integer        module = int(moduleName)    except TypeError:        raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND    modules = netbox.getChildren(manage.Module,                    where="module='%s'" % module)    if not modules:        raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND    return modules[0]class ModuleInfo(manage.Module):    def showModule(self, perspective='standard', interval=30):        def findDisplayWidth(ports):            # Normally we'll show 12 ports in a row, but            # sometimes (?) 16 could be the one.            length = len(ports)            for x in 12,16,8,14:                if not length % x:                    return x            return 12        def perspectiveStandard(port, portView):            """Return module view from the standard status perspective"""            titles = []            if port.interface:                # Add the interface name to the popup title                titles.append(port.interface)            if port.speed:                portView['class'] += ' Mb%d' % port.speed                title = '%d Mbit' % port.speed                if port.to_netbox:                    title += ' -> %s' % port.to_netbox                titles.append(title)            if type == 'sw':                if port.link == 'd':                    portView['class'] += ' disabled'                    titles.append('disabled')                elif port.link <> 'y':                    portView['class'] += ' passive'                    titles.append('inactive')                if port.trunk:                    portView['class'] += ' trunk'                    titles.append("trunk")                if port.duplex:                    portView['class'] += ' %sduplex' % port.duplex                if port.duplex == 'h':                    titles.append("half duplex")                elif port.duplex == 'f':                    titles.append("full duplex")                if port.media:                    titles.append(port.media)                vlans = port.getChildren(manage.Swportvlan)                if vlans:                    vlans = [x.vlan for x in vlans]                    vlans = map(lambda x: manage.Vlan(x), vlans)                    vlans = [str(x.vlan) for x in vlans]                    titles.append('Vlan ' + ','.join(vlans))                blocked = port.getChildren(manage.Swportblocked)                if blocked:                    portView['class'] += ' blocked'                    vlans = [str(block.vlan) for block in blocked]                    titles.append("blocked " + ','.join(vlans))            if type == 'gw':                if port.portname:                    titles.append(port.portname)            return titles        def perspectiveActive(port, portView):            """Return module view from the 'last active ports' perspective"""            titles = []            if port.interface:                # Add the interface name to the popup title                titles.append(port.interface)            if port.ifindex in active:                daysago = int(active[port.ifindex])                if daysago > 1:                    titles.append("%d days ago" % active[port.ifindex])                elif daysago == 1:                    titles.append("%d day ago" % active[port.ifindex])                else:                    titles.append("used today")                bgcolor = gradient[daysago]                portView['style'] = 'background-color: #%s;' % \                                    util.colortohex(bgcolor)                portView['class'] +=  ' active'            if port.link == 'y':                titles.append('active now')                try:                    portView['style']                except:                    portView['style'] = 'background-color: #%s;' % \                                        util.colortohex(gradient[0])                portView['class'] +=  ' active link'            if portView['class'].count('active') == 0:                titles.append('free')                portView['class'] +=  ' inactive'            return titles        def getActive():            """Return a dictionary of CAM activity per ifindex.            ifindex => days since last CAM entry            """            # XXX: This is a hack, but caching of this result set reduces page            # response time by about 75%            global active_cache            # Remove expired cache entries            # Removing items during iteration causes a RuntimeError, so this            # has to be done in two steps.            expired = []            for key, value in active_cache.iteritems():                if value['expires_at'] < datetime.now():                    expired.append(key)            for key in expired:                del active_cache[key]            # If cached, get result from cache            cache_key = (self.netbox.netboxid, interval)            if cache_key in active_cache:                return active_cache[cache_key]['result']            sql = \                """                SELECT ifindex,                       EXTRACT(days FROM                               CASE WHEN MAX(end_time) = 'infinity' THEN interval '0 days'                               ELSE NOW() - MAX(end_time)                               END) AS days_ago                FROM cam                WHERE end_time > NOW() - interval '%d days'                AND netboxid=%s                GROUP BY ifindex                ORDER BY ifindex"""            cursor = self.cursor()            cursor.execute(sql, (interval, self.netbox.netboxid,))            active_cache[cache_key] = {                'result': dict(cursor.fetchall()),                'expires_at': datetime.now() + timedelta(seconds=60),            }            return active_cache[cache_key]['result']        def sortPortsByInterfaceName(ports):            """Do natural sort of ports by interface name"""            import nav.natsort            map = {}            list = []            rest = []            for port in ports:                if port.interface is not None:                    map[port.interface] = port                    list.append(port.interface)                else:                    rest.append(port)            list.sort(nav.natsort.inatcmp)            result = []            for port in list:                result.append(map[port])            result.extend(rest)            return result        def filterInterfaceName(name):            """Filter interface names from ifDescr to ifName style"""            filters = (                ('Vlan', 'Vl'),                ('TenGigabitEthernet', 'Te'),                ('GigabitEthernet', 'Gi'),                ('FastEthernet', 'Fa'),                ('Ethernet', 'Et'),                ('Loopback', 'Lo'),                ('Tunnel', 'Tun'),                ('Serial', 'Se'),                ('Dialer', 'Di'),                ('-802.1Q vLAN subif', ''),                ('-ISL vLAN subif', ''),                ('-aal5 layer', ''),            )            for old, new in filters:                name = str(name).replace(old, new)            return name        if perspective.startswith('gw'):            ports = self.getChildren(manage.Gwport, orderBy=('interface'))            type = "gw"        else:            ports = self.getChildren(manage.Swport, orderBy=('interface'))            type = "sw"        if not ports:            return None        ports = sortPortsByInterfaceName(ports)        moduleView = html.Division(_class="module")        if type == "gw":            moduleView['class'] += ' gw'        moduleView.append(html.Header(            urlbuilder.createLink(self, content=self.module),            level=3))        # calc width        width = findDisplayWidth(ports)        count = 0        portTable = html.Table()        moduleView.append(portTable)        row = html.TableRow()        if perspective == 'active':            active = getActive()            gradient = util.color_gradient(color_recent, color_longago,                                           interval)        for port in ports:            if count and not count % width:                portTable.append(row)                row = html.TableRow()            count += 1            if type == 'gw':                portNr = port.interface            else:                portNr = port.interface or port.port or port.ifindex            portNr = filterInterfaceName(portNr)            portView = html.TableCell(urlbuilder.createLink(port, content=portNr), _class="port")            row.append(portView)            portView['title'] = ""            if perspective == 'active':                titles = perspectiveActive(port, portView)            else:                titles = perspectiveStandard(port, portView)            if titles:                # beautiful! but .capitalize() lowercases everything first                titles[0] = titles[0][0].upper() + titles[0][1:]                title = ', '.join(titles)                portView['title'] = title        portTable.append(row)        return moduleViewdef showModuleLegend(perspective='standard', interval=30):    result = html.Division(_class="legend")    legendtable = html.Table()    def mkLegend(name, descr, style=None):        port = html.Span("11")        port['class'] = "port %s" % name        if style:            port['style'] = style        legenditem = html.TableCell()        legenditem.append(port)        legenditem.append(descr)        return legenditem    def legendSpeed():        legend = html.TableRow()        legend.append(html.TableCell(html.Big("Speed legend")))        legend.append(mkLegend("passive", "Not active"))        legend.append(mkLegend("disabled", "Disabled"))        legend.append(mkLegend("Mb10", "10 Mbit"))        legend.append(mkLegend("Mb100", "100 Mbit"))        legend.append(mkLegend("Mb1000", "1 Gbit"))        legend.append(mkLegend("Mb10000", "10 Gbit"))        legendtable.append(legend)    def legendFrame():        legend = html.TableRow()        legend.append(html.TableCell(html.Big("Frame legend")))        legend.append(mkLegend("hduplex", "Half duplex"))        legend.append(mkLegend("fduplex", "Full duplex"))        legend.append(mkLegend("trunk", "Trunk"))        legend.append(mkLegend("blocked", "Blocked"))        legend.append(html.TableCell())        legend.append(html.TableCell())        legendtable.append(legend)    def legendActive():        legend = html.TableRow()        legend.append(html.TableCell(html.Big("Activity legend")))        legend.append(mkLegend("inactive", "Not used in %d days" % interval))        legend.append(mkLegend("active", "Used last %d days" % interval,            "background-color: #%s" % util.colortohex(color_longago)))        legend.append(mkLegend("active", "Used today",            "background-color: #%s" % util.colortohex(color_recent)))        legend.append(mkLegend("active link", "Active now",            "background-color: #%s" % util.colortohex(color_recent)))        legend.append(html.TableCell())        legend.append(html.TableCell())        legendtable.append(legend)    if not type(perspective) is list:        perspective = [perspective]    legends = Set()    if 'gwstandard' in perspective:        legends.add((1, legendSpeed))    if 'standard' in perspective:        legends.add((1, legendSpeed))        legends.add((2, legendFrame))    if 'active' in perspective:        legends.add((3, legendActive))    legends = list(legends)    legends.sort()    for order, legend in legends:        legend()    result.append(html.Division(legendtable))    result.append(html.Paragraph(html.Emphasis("Hold mouse over port for info, click for details")))    return result

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -