2019-03-01 20:41:13 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!
|
2019-03-01 20:41:13 +01:00
|
|
|
____ ____ ______ __ __ __ _____
|
|
|
|
|
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
|
|
|
|
|
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
|
|
|
|
|
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
|
|
|
|
|
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
|
|
|
|
|
German BOS Information Script
|
|
|
|
|
by Bastian Schroll
|
|
|
|
|
|
2019-03-04 14:48:25 +01:00
|
|
|
@file: routerManager.py
|
|
|
|
|
@date: 04.03.2019
|
2019-03-01 20:41:13 +01:00
|
|
|
@author: Bastian Schroll
|
2019-03-04 14:48:25 +01:00
|
|
|
@description: Class for the BOSWatch packet router manager class
|
2019-03-01 20:41:13 +01:00
|
|
|
"""
|
2019-03-04 14:48:25 +01:00
|
|
|
|
2019-03-01 21:36:38 +01:00
|
|
|
# todo think about implement threading for routers and the plugin calls (THREAD SAFETY!!!)
|
2019-03-01 20:41:13 +01:00
|
|
|
import logging
|
|
|
|
|
import importlib
|
2019-10-25 14:33:18 +02:00
|
|
|
import time
|
2019-03-02 09:17:20 +01:00
|
|
|
from boswatch.configYaml import ConfigYAML
|
2019-03-04 14:48:25 +01:00
|
|
|
from boswatch.router.router import Router
|
|
|
|
|
from boswatch.router.route import Route
|
2019-03-01 20:41:13 +01:00
|
|
|
|
|
|
|
|
logging.debug("- %s loaded", __name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RouterManager:
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Class to manage all routers"""
|
2021-02-16 01:09:04 +01:00
|
|
|
|
2019-03-01 20:41:13 +01:00
|
|
|
def __init__(self):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Create new router"""
|
2019-03-01 22:12:29 +01:00
|
|
|
self._routerDict = {}
|
2019-10-25 14:33:18 +02:00
|
|
|
self._startTime = int(time.time())
|
2019-03-01 20:41:13 +01:00
|
|
|
|
2019-03-02 09:17:20 +01:00
|
|
|
# if there is an error, router list would be empty (see tmp variable)
|
2019-10-25 15:56:20 +02:00
|
|
|
def buildRouters(self, config):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Initialize Routers from given config file
|
2019-03-04 20:10:49 +01:00
|
|
|
|
|
|
|
|
@param config: instance of ConfigYaml class
|
|
|
|
|
@return True or False"""
|
2019-03-01 22:12:29 +01:00
|
|
|
self._routerDict = {} # all routers and instances of modules/plugins would be destroyed
|
2019-03-01 22:46:28 +01:00
|
|
|
routerDict_tmp = {}
|
2019-03-01 20:41:13 +01:00
|
|
|
logging.debug("build routers")
|
|
|
|
|
|
|
|
|
|
# first we have to init all routers
|
|
|
|
|
# because a router can be a valid target and we need his reference
|
|
|
|
|
for router in config.get("router"):
|
2019-03-02 09:17:20 +01:00
|
|
|
if router.get("name") is None or router.get("route") is None:
|
|
|
|
|
logging.error("name or route not found in router: %s", router)
|
|
|
|
|
return False
|
2019-03-01 22:46:28 +01:00
|
|
|
if router.get("name") in self._routerDict:
|
|
|
|
|
logging.error("duplicated router name: %s", router.get("name"))
|
|
|
|
|
return False
|
2019-03-04 14:48:25 +01:00
|
|
|
routerDict_tmp[router.get("name")] = Router(router.get("name"))
|
2019-03-01 21:36:38 +01:00
|
|
|
|
2019-03-01 20:41:13 +01:00
|
|
|
for router in config.get("router"):
|
2019-03-02 09:17:20 +01:00
|
|
|
routerName = router.get("name")
|
2019-03-01 22:46:28 +01:00
|
|
|
|
2019-03-01 20:41:13 +01:00
|
|
|
for route in router.get("route"):
|
2019-03-01 21:36:38 +01:00
|
|
|
routeType = route.get("type")
|
2019-10-25 11:12:41 +02:00
|
|
|
routeRes = route.get("res")
|
|
|
|
|
routeName = route.get("name", default=routeRes)
|
|
|
|
|
|
2019-03-09 12:12:35 +01:00
|
|
|
routeConfig = route.get("config", default=ConfigYAML()) # if no config - build a empty
|
2019-03-01 21:36:38 +01:00
|
|
|
|
2019-10-25 11:12:41 +02:00
|
|
|
if routeType is None or routeRes is None:
|
2019-03-01 22:46:28 +01:00
|
|
|
logging.error("type or name not found in route: %s", route)
|
|
|
|
|
return False
|
2019-03-01 21:36:38 +01:00
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if routeType == "plugin":
|
2019-10-25 11:12:41 +02:00
|
|
|
importedFile = importlib.import_module(routeType + "." + routeRes)
|
2019-03-02 09:17:20 +01:00
|
|
|
loadedClass = importedFile.BoswatchPlugin(routeConfig)
|
2019-10-25 15:36:10 +02:00
|
|
|
routerDict_tmp[routerName].addRoute(Route(routeName,
|
|
|
|
|
loadedClass._run,
|
|
|
|
|
loadedClass._getStatistics,
|
|
|
|
|
loadedClass._cleanup))
|
2019-03-01 21:36:38 +01:00
|
|
|
|
|
|
|
|
elif routeType == "module":
|
2019-10-25 11:12:41 +02:00
|
|
|
importedFile = importlib.import_module(routeType + "." + routeRes)
|
2019-03-02 09:17:20 +01:00
|
|
|
loadedClass = importedFile.BoswatchModule(routeConfig)
|
2019-10-25 15:36:10 +02:00
|
|
|
routerDict_tmp[routerName].addRoute(Route(routeName,
|
|
|
|
|
loadedClass._run,
|
|
|
|
|
loadedClass._getStatistics,
|
|
|
|
|
loadedClass._cleanup))
|
2019-03-01 21:36:38 +01:00
|
|
|
|
|
|
|
|
elif routeType == "router":
|
2019-10-28 09:05:14 +01:00
|
|
|
routerDict_tmp[routerName].addRoute(Route(routeName, routerDict_tmp[routeRes].runRouter))
|
2019-03-01 21:36:38 +01:00
|
|
|
|
|
|
|
|
else:
|
2019-03-01 22:46:28 +01:00
|
|
|
logging.error("unknown type '%s' in %s", routeType, route)
|
|
|
|
|
return False
|
2019-03-01 21:36:38 +01:00
|
|
|
|
2021-02-28 13:58:29 +01:00
|
|
|
except ModuleNotFoundError:
|
|
|
|
|
logging.exception("%s not found: %s", route.get("type"), route.get("res"))
|
2019-03-01 22:46:28 +01:00
|
|
|
return False
|
2019-03-01 22:12:29 +01:00
|
|
|
|
2019-03-01 21:36:38 +01:00
|
|
|
logging.debug("finished building routers")
|
2019-03-01 22:46:28 +01:00
|
|
|
self._routerDict = routerDict_tmp
|
2019-03-01 21:36:38 +01:00
|
|
|
self._showRouterRoute()
|
2019-03-01 22:46:28 +01:00
|
|
|
return True
|
2019-03-01 20:41:13 +01:00
|
|
|
|
2019-10-25 13:27:48 +02:00
|
|
|
def runRouters(self, routerRunList, bwPacket):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Run given Routers
|
2019-03-04 20:10:49 +01:00
|
|
|
|
|
|
|
|
@param routerRunList: string or list of router names in string form
|
|
|
|
|
@param bwPacket: instance of Packet class"""
|
2019-03-02 09:17:20 +01:00
|
|
|
if type(routerRunList) is str: # convert single string name to list
|
|
|
|
|
routerRunList = [routerRunList]
|
2019-03-01 22:12:29 +01:00
|
|
|
|
2019-03-02 09:17:20 +01:00
|
|
|
for routerName in routerRunList:
|
2019-03-01 22:12:29 +01:00
|
|
|
if routerName in self._routerDict:
|
|
|
|
|
self._routerDict[routerName].runRouter(bwPacket)
|
2019-10-21 20:56:51 +02:00
|
|
|
else:
|
|
|
|
|
logging.warning("unknown router: %s", routerName)
|
2019-03-01 20:41:13 +01:00
|
|
|
|
2019-10-25 14:33:18 +02:00
|
|
|
self._saveStats() # write stats to stats file
|
|
|
|
|
|
2019-10-25 15:36:10 +02:00
|
|
|
def cleanup(self):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Run cleanup routines for all loaded route points"""
|
2019-10-25 15:36:10 +02:00
|
|
|
for name, routerObject in self._routerDict.items():
|
|
|
|
|
logging.debug("Start cleanup for %s", name)
|
|
|
|
|
for routePoint in routerObject.routeList:
|
|
|
|
|
if routePoint.cleanup:
|
|
|
|
|
routePoint.cleanup()
|
|
|
|
|
|
2019-03-01 21:36:38 +01:00
|
|
|
def _showRouterRoute(self):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Show the routes of all routers"""
|
2019-03-02 09:17:20 +01:00
|
|
|
for name, routerObject in self._routerDict.items():
|
2019-03-01 20:41:13 +01:00
|
|
|
logging.debug("Route for %s", name)
|
2019-03-02 09:17:20 +01:00
|
|
|
counter = 0
|
|
|
|
|
for routePoint in routerObject.routeList:
|
|
|
|
|
counter += 1
|
|
|
|
|
logging.debug(" %d. %s", counter, routePoint.name)
|
2019-10-25 14:33:18 +02:00
|
|
|
|
|
|
|
|
def _saveStats(self):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Save current statistics to file"""
|
2019-10-25 14:33:18 +02:00
|
|
|
lines = []
|
|
|
|
|
for name, routerObject in self._routerDict.items():
|
|
|
|
|
lines.append("[" + name + "]")
|
2019-10-25 15:36:10 +02:00
|
|
|
lines.append(" - Route points: " + str(len(routerObject.routeList)))
|
2019-10-25 15:54:26 +02:00
|
|
|
lines.append(" - Runs: " + str(routerObject._getStatistics()['runCount']))
|
2019-10-25 14:33:18 +02:00
|
|
|
for routePoint in routerObject.routeList:
|
|
|
|
|
lines.append("[+] " + routePoint.name)
|
|
|
|
|
if routePoint.statistics:
|
2019-10-25 14:40:49 +02:00
|
|
|
if routePoint.statistics()['type'] == "module":
|
|
|
|
|
lines.append(" - Runs: " + str(routePoint.statistics()['runCount']))
|
|
|
|
|
lines.append(" - Run errors: " + str(routePoint.statistics()['moduleErrorCount']))
|
|
|
|
|
elif routePoint.statistics()['type'] == "plugin":
|
|
|
|
|
lines.append(" - Runs: " + str(routePoint.statistics()['runCount']))
|
|
|
|
|
lines.append(" - Setup errors: " + str(routePoint.statistics()['setupErrorCount']))
|
|
|
|
|
lines.append(" - Alarm errors: " + str(routePoint.statistics()['alarmErrorCount']))
|
|
|
|
|
lines.append(" - Teardown errors: " + str(routePoint.statistics()['teardownErrorCount']))
|
2019-10-25 14:33:18 +02:00
|
|
|
lines.append("")
|
|
|
|
|
|
|
|
|
|
with open("stats_" + str(self._startTime) + ".txt", "w") as stats:
|
|
|
|
|
for line in lines:
|
|
|
|
|
stats.write(line + "\n")
|