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

📄 maintengine.py

📁 Network Administration Visualized 网络管理可视化源码
💻 PY
字号:
#!/usr/bin/env python# -*- coding: ISO-8859-1 -*-## Copyright 2003-2005 Norwegian University of Science and Technology# Copyright 2006 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: Bj鴕n Ove Gr鴗an <bjorn.grotan@itea.ntnu.no>, 2003#          Sigurd Gartmann <sigurd-nav@brogar.org>, 2004#          Stein Magnus Jodal <stein.magnus.jodal@uninett.no>, 2006#"""This program dispatches maintenance events according to the maintenanceschedule in NAVdb."""__copyright__ = "Copyright 2003-2005 NTNU, 2006 UNINETT AS"__license__ = "GPL"__author__ = "Bj鴕n Ove Gr鴗an (bjorn.grotan@itea.ntnu.no), Sigurd Gartmann (sigurd-nav@brogar.org), Stein Magnus Jodal (stein.magnus.jodal@uninett.no)"__id__ = "$Id: maintengine.py 3963 2007-04-12 08:58:37Z mortenv $"import loggingimport os.pathimport sysimport nav.dbimport nav.eventimport nav.logsfrom mx import DateTimelogfile = os.path.join(nav.path.localstatedir, 'log', 'maintengine.log')logformat = "[%(asctime)s] [%(levelname)s] [pid=%(process)d %(name)s] %(message)s"logger = logging.getLogger('maintengine')# Placeholdersevents = []states = ['scheduled', 'active', 'passed', 'canceled']debug = FalseboxesOffMaintenance = []dbconn = nav.db.getConnection('eventEngine', 'manage')dbconn.autocommit(0)# Make sure isolation level is "read committed", not "serialized"dbconn.set_isolation_level(1)db = dbconn.cursor()def loginit():    """Initialize logging setup"""    global _loginited    try:        # Make sure we don't initialize logging setup several times (in case        # of module reloads and such)        if _loginited:            return    except:        pass    root = logging.getLogger('')    formatter = logging.Formatter(logformat)    try:        handler = logging.FileHandler(logfile)    except IOError, e:        # Most likely, we were denied access to the log file.        # We silently ignore it and log nothing :-P        pass    else:        handler.setFormatter(formatter)        root.addHandler(handler)        nav.logs.setLogLevels()        _loginited = Truedef schedule():    """Check if there are maintenance tasks to be schedule"""    sql = """UPDATE maint_task SET state = 'scheduled'        WHERE state IS NULL        OR state NOT IN ('scheduled', 'active', 'passed', 'canceled')"""    db.execute(sql)    dbconn.commit()    def check_state():    """Checks if there are some maintenance tasks to be set active or    passed."""    sql = """SELECT maint_taskid FROM maint_task        WHERE maint_start < NOW() AND state = 'scheduled'"""    db.execute(sql)    for (taskid,) in db.fetchall():        e = {}        e['type'] = 'active'        e['taskid'] = taskid        events.append(e)            sql = """SELECT maint_taskid FROM maint_task        WHERE maint_end < NOW() AND state = 'active'"""    db.execute(sql)    for (taskid,) in db.fetchall():        e = {}        e['type'] = 'passed'        e['taskid'] = taskid        events.append(e)    # FIXME: Create some magic to check overlapping timeframes with overlapping    # componentsdef send_event():    """Sends events to the event queue."""    for e in events:        type = e['type']        taskid = e['taskid']        # Get all components related to task/event        sql = """SELECT key, value FROM maint_component                 WHERE maint_taskid = %(maint_taskid)d"""        data = { 'maint_taskid': taskid }        db.execute(sql, data)            for (key, val) in db.fetchall():            # Prepare event variables            target = 'eventEngine'            subsystem = 'maintenance'            source = subsystem            severity = 50            eventtype = 'maintenanceState'            if type == 'active':                state = 's' # s = start                value = 100            elif type == 'passed':                state = 'e' # e = end                value = 0            # Get all related netboxes            netboxes = []            if key in ('location', 'room'):                if key == 'location':                    sql = """SELECT netboxid, sysname, deviceid                        FROM netbox INNER JOIN room USING (roomid)                        WHERE locationid = %(locationid)s"""                    data = { 'locationid': val }                    logger.debug("location query: %s", sql % data)                    db.execute(sql, data)                    logger.debug("location number of results: %d", db.rowcount)                elif key == 'room':                    sql = """SELECT netboxid, sysname, deviceid                        FROM netbox                        WHERE roomid = %(roomid)s"""                    data = { 'roomid': val }                    logger.debug("room query: %s", sql % data)                    db.execute(sql, data)                    logger.debug("room number of results: %d", db.rowcount)                for (netboxid, sysname, deviceid) in db.fetchall():                    netboxes.append({ 'netboxid': netboxid,                                      'sysname': sysname,                                      'deviceid': deviceid,                                      'cvar': 'netbox',                                      'cval': sysname })            elif key == 'netbox':                sql = """SELECT netboxid, sysname, deviceid                    FROM netbox                    WHERE netboxid = %(netboxid)d"""                data = { 'netboxid': int(val) }                logger.debug("netbox query: %s", sql % data)                db.execute(sql, data)                logger.debug("netbox number of results: %d", db.rowcount)                result = db.fetchone()                if result:                    (netboxid, sysname, deviceid) = result                    netboxes.append({ 'netboxid': netboxid,                                      'sysname': sysname,                                      'deviceid': deviceid,                                      'cvar': 'netbox',                                      'cval': sysname })            elif key == 'service':                sql = """SELECT netboxid, sysname, deviceid, handler                    FROM service INNER JOIN netbox USING (netboxid)                    WHERE serviceid = %(serviceid)d"""                data = { 'serviceid': int(val) }                logger.debug("service query: %s", sql % data)                db.execute(sql, data)                logger.debug("service number of results: %d", db.rowcount)                result = db.fetchone()                if result:                    (netboxid, sysname, deviceid, handler) = result                    netboxes.append({ 'netboxid': netboxid,                                      'sysname': sysname,                                      'deviceid': deviceid,                                      'serviceid': int(val),                                      'servicename': handler,                                      'cvar': 'service',                                      'cval': handler })            elif key == 'module':                # Unsupported as of NAV 3.2                raise DeprecationWarning, "Deprecated component key"            # Create events for all related netboxes            for netbox in netboxes:                # Append to list of boxes taken off maintenance during this run                if type == 'passed':                    boxesOffMaintenance.append(netbox['netboxid'])                 if netbox.has_key('serviceid'):                    subid = netbox['serviceid']                else:                    subid = None                # Create event                event = nav.event.Event(source=source, target=target,                    deviceid=netbox['deviceid'],                    netboxid=netbox['netboxid'], subid=subid,                    eventtypeid=eventtype, state=state, value=value,                    severity=severity)                event[netbox['cvar']] = netbox['cval']                event['maint_taskid'] = taskid                # Add event to eventq                result = event.post()                logger.debug("Event: %s, Result: %s", event, result)        # Update state        sql = """UPDATE maint_task            SET state = %(state)s            WHERE maint_taskid = %(maint_taskid)d"""        data = { 'state': type,                 'maint_taskid': taskid }        db.execute(sql, data)        # Commit transaction        dbconn.commit()def remove_forgotten():    """    Remove 'forgotten' netboxes from their maintenance state.    Sometimes, like when netboxes have been deleted from a maintenance task    during its active maintenance window, we will no longer know that the box    has gone on maintenenance and should be taken off. This function takes all    'forgotten' netboxes off maintenance.    """    # This SQL retrieves a list of boxes that are currently on    # maintenance, according to the alert history.    sqlactual = """SELECT ah.netboxid, ah.deviceid, n.sysname, subid         FROM alerthist ah LEFT JOIN netbox n USING (netboxid)        WHERE eventtypeid='maintenanceState' AND netboxid IS NOT NULL        AND end_time = 'infinity'"""    # This SQL retrieves a list of boxes that are supposed to be on    # maintenance, according to the schedule.    sqlsched = """SELECT n.netboxid, n.deviceid, n.sysname, NULL AS subid        FROM maint m INNER JOIN netbox n ON (n.netboxid = m.value)        WHERE m.key = 'netbox' AND m.state = 'active'        UNION        SELECT n.netboxid, n.deviceid, n.sysname, NULL AS subid        FROM maint m INNER JOIN netbox n ON (n.roomid = m.value)        WHERE m.key = 'room' AND m.state = 'active'        UNION        SELECT n.netboxid, n.deviceid, n.sysname, NULL AS subid        FROM maint m INNER JOIN netbox n ON (n.roomid IN            (SELECT roomid FROM room WHERE locationid = m.value))        WHERE m.key = 'location' AND m.state = 'active'        UNION                SELECT n.netboxid, n.deviceid, n.sysname, m.value AS subid        FROM maint m INNER JOIN netbox n ON (n.netboxid IN            (SELECT netboxid FROM service WHERE                serviceid LIKE m.value))        WHERE m.key = 'service' AND m.state = 'active'"""    # The full SQL is a set operation to select all boxes that are    # currently on maintenance and subtracts those that are supposed    # to be on maintenance - resulting in a list of boxes that should    # be taken off maintenance immediately.    sqlfull = "(%s) \n EXCEPT \n (%s)" % (sqlactual, sqlsched)    db.execute(sqlfull)    target = 'eventEngine'    subsystem = 'maintenance'    source = subsystem    severity = 50    eventtype = 'maintenanceState'    state = 'e'    value = 0    for (netboxid, deviceid, sysname, subid) in db.fetchall():        if netboxid in boxesOffMaintenance:            # MaintenenceOff-events posted during this run might not            # have been processed by eventEngine yet. We discard these            # boxes here.            continue        # If it's a service, we have to set subid also        if subid is None:            logger.info("Box %s (%d) is on unscheduled maintenance. " +                        "Taking off maintenance now.", sysname, netboxid)            subid = False        else:            logger.info("Service (%d) at box %s (%d) is on unscheduled " +                        "maintenance. Taking off maintenance...",                        subid, sysname, netboxid)            subid = int(subid)        # Create event        event = nav.event.Event(source=source, target=target,            deviceid=deviceid, netboxid=netboxid, subid=subid,            eventtypeid=eventtype, state=state, value=value, severity=severity)        result = event.post()        logger.debug("Event: %s, Result: %s", event, result)    # Commit transaction    dbconn.commit()if __name__ == '__main__':    loginit()    schedule()    check_state()    send_event()    remove_forgotten()

⌨️ 快捷键说明

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