linspector-old/lib/config/parser.py

233 lines
8.5 KiB
Python
Raw Normal View History

2013-06-11 04:52:20 +02:00
from os.path import isfile
2013-06-11 01:21:18 +02:00
import json
2013-06-18 00:10:14 +02:00
import sys
import imp
2013-06-11 01:21:18 +02:00
from layouts import Layout
from hostgroups import HostGroup
2013-06-18 00:10:14 +02:00
from members import Member
from periods import CronPeriod, DatePeriod, IntervalPeriod
2013-06-11 01:21:18 +02:00
2013-06-18 00:10:14 +02:00
from lib.services.service import Service
print id(Service)
2013-06-18 00:10:14 +02:00
from lib.processors.processor import Processor
from lib.parsers.parser import Parser
from lib.tasks.task import Task
2013-06-18 01:50:01 +02:00
2013-06-18 00:10:14 +02:00
MOD_SERVICES = "services"
MOD_PROCESSORS = "processors"
MOD_PARSERS = "parsers"
MOD_TASKS = "tasks"
2013-06-18 00:10:14 +02:00
KEY_LAYOUTS = "layouts"
KEY_HOSTGROUPS = "hostgroups"
KEY_MEMBERS = "members"
KEY_PERIODS = "periods"
KEY_CORE = "core"
2013-06-11 01:21:18 +02:00
class ConfigurationException(Exception):
def __init__(self, msg, log):
log.e(msg)
self.msg = msg
def __str__(self):
return repr(self.msg)
class ConfigParser:
def __init__(self, log):
2013-06-18 02:58:40 +02:00
"""
2013-06-11 01:21:18 +02:00
initializes a new ConfigParser Object
params:
log: pre configured logger Object to post messages while parsing"
2013-06-18 02:58:40 +02:00
"""
2013-06-11 01:21:18 +02:00
self.log = log
self.hostgroups = {}
self.members = {}
self.periods = {}
2013-06-18 00:10:14 +02:00
self.layouts = {}
2013-06-19 01:56:04 +02:00
self._loadedMods={MOD_SERVICES: {}, MOD_PROCESSORS: {}, MOD_TASKS: {}, MOD_PARSERS: {}}
2013-06-18 00:10:14 +02:00
def _create_new_config_dict(self):
2013-06-19 01:56:04 +02:00
return {"members": {}, "periods": {}, "hostgroups": {}, "layouts": {}, "core": {}}
2013-06-18 00:10:14 +02:00
def create_config(self, config):
configDict = self._create_new_config_dict()
for layout in config.get_layouts():
layout._to_config_dict(configDict)
2013-06-11 04:52:20 +02:00
2013-06-11 01:21:18 +02:00
def _read_json_config(self, configFilename):
2013-06-18 02:58:40 +02:00
"""
2013-06-11 01:21:18 +02:00
reads the config File and returns a dictionary, while lowering the first keys
params:
configFilename: the path under which the configuration file should be found
2013-06-18 02:58:40 +02:00
"""
2013-06-11 04:52:20 +02:00
if not isfile(configFilename):
2013-06-11 01:21:18 +02:00
msg = "config file not found at " + str(configFilename)
raise ConfigurationException(msg, self.log)
self.configfilename = configFilename
with open(configFilename) as cfgFile:
config = cfgFile.read()
self.log.i("reading Config: " + configFilename)
return json.loads(config)
2013-06-18 00:10:14 +02:00
def _create_raw_Object(self, jsonDict, msgName, creator):
items = []
for key, val in jsonDict.items():
try:
item = creator(key, val)
items.append(item)
except Exception:
self.log.w("ignoring " + msgName + ": " + key + "! reason:")
self.log.w(str(Exception))
return items
2013-06-11 01:21:18 +02:00
2013-06-18 00:10:14 +02:00
def _load_module(self, clazz, modPart):
mods = self._loadedMods[modPart]
if clazz in mods:
return mods["class"]
else:
2013-06-18 02:19:50 +02:00
mod = __import__(clazz)
#path = join("lib", modPart, clazz + ".py")
#mod = imp.load_source(clazz, path)
2013-06-18 02:19:50 +02:00
mods[clazz] = mod
2013-06-18 02:19:09 +02:00
return mod
2013-06-18 00:10:14 +02:00
def replace_with_import(self, objList, modPart, items_func, class_check):
for obj in objList:
repl = []
items = items_func(obj)
for clazzItem in items:
try:
clazz = clazzItem["class"]
path = "lib/" + modPart
sys.path.append(path)
2013-06-18 00:10:14 +02:00
mod = self._load_module(clazz, modPart)
item = mod.create(clazzItem)
repl.append(item)
#TODO: activate the crappy classcheck if answer is provided
#http://stackoverflow.com/questions/17179440/
self.log.d("warning: instance_check isn't working yet! TRUST_ALL = TRUE")
#if class_check(item):
# repl.append(item)
#else:
# self.log.w(" ignoring class " + clazzItem["class"] + "! It does not pass the class check!")
2013-06-18 00:10:14 +02:00
except ImportError, err:
self.log.w("could not import " + clazz + ": " + str(clazzItem) + "! reason")
self.log.w(str(err))
except KeyError, k:
self.log.w("Key '" + str(k) + "' not in classItem " + str(clazzItem))
except Exception, e:
self.log.w("Error while replace: " + clazz + str(e))
finally:
if path in sys.path:
del sys.path[sys.path.index(path)]
2013-06-18 00:10:14 +02:00
del items[:]
items.extend(repl)
def replace_pointer(self, objectList, replObjectList, id_list_func, id_get_func):
for obj in objectList:
replacements = []
idList = id_list_func(obj)
for id in idList:
repl = [o for o in replObjectList if id == id_get_func(o)]
if len(repl) == 1:
replacements.append(repl[0])
del idList[:]
idList.extend(replacements)
2013-06-11 01:21:18 +02:00
def parse_config(self, configFilename):
2013-06-19 01:56:04 +02:00
pass
2013-06-18 00:10:14 +02:00
def parsePeriodList(name, values):
if "date" in values:
return DatePeriod(name, **values)
comp = ["weeks", "days", "hours", "minutes", "seconds", "start_date"]
if len([i for i in comp if i in values]) > 0 :
return IntervalPeriod(name, **values)
comp = ["year", "month", "day", "week", "day_of_week", "hour", "minute", "second"]
if len([i for i in comp if i in values]) > 0 :
return CronPeriod(name, **values)
else:
raise ConfigurationException("could not determine correct Period(" + repr(values)+").")
2013-06-18 02:58:40 +02:00
2013-06-18 00:10:14 +02:00
class FullConfigParser(ConfigParser):
def parse_config(self, configFilename):
2013-06-18 02:58:40 +02:00
"""
2013-06-18 00:10:14 +02:00
parses the json configuration and returns a list of layouts,
which contains all nessesary information of the config file.
parses the full config
Parsing will be done in 3 steps:
1. get raw Config Objects by just passing the values defined inside the config
2. replace references by objects, import services, tasks, parsers and processors
3. do sanity checks
params:
configFilename: indicates which configuration file to parse
2013-06-18 02:58:40 +02:00
"""
2013-06-18 00:10:14 +02:00
self.jsonDict = self._read_json_config(configFilename)
# first step
creator = lambda name, values: Layout(name,**values)
layouts = self._create_raw_Object(self.jsonDict[KEY_LAYOUTS], "Layout", creator)
creator = lambda name, values: Member(name, **values)
members = self._create_raw_Object(self.jsonDict[KEY_MEMBERS], "Member", creator)
creator = lambda name, values: HostGroup(name, **values)
hostgroups = self._create_raw_Object(self.jsonDict[KEY_HOSTGROUPS], "Hostgroup", creator)
creator = parsePeriodList
periods = self._create_raw_Object(self.jsonDict[KEY_PERIODS], "Period", creator)
2013-06-18 00:10:14 +02:00
#2. import and replace
items_func = lambda hostgroup: hostgroup.get_services()
class_check = lambda service: isinstance(service, Service)
self.replace_with_import(hostgroups, MOD_SERVICES, items_func, class_check)
items_func = lambda hostgroup: hostgroup.get_processors()
class_check = lambda processor: isinstance(processor, Processor)
self.replace_with_import(hostgroups, MOD_PROCESSORS, items_func, class_check)
services = []
for hg in hostgroups:
services.extend(hg.get_services())
2013-06-18 00:10:14 +02:00
items_func = lambda service: service.get_parser()
class_check = lambda parser: isinstance(parser, Parser)
self.replace_with_import(services, MOD_PARSERS, items_func, class_check)
2013-06-18 00:10:14 +02:00
items_func = lambda member: member.get_tasks()
class_check = lambda task: isinstance(task, Task)
self.replace_with_import(members, MOD_TASKS, items_func, class_check)
#replace object pointer
id_list_func = lambda hostgroup: hostgroup.get_members()
id_get_func = lambda member: member.id
self.replace_pointer(hostgroups, members, id_list_func, id_get_func)
id_list_func = lambda service: service.get_periods()
id_get_func = lambda period: period.get_name()
self.replace_pointer(services, periods, id_list_func, id_get_func)
id_list_func = lambda layout: layout.get_hostgroups()
id_get_func = lambda hostgroup: hostgroup.get_name()
self.replace_pointer(layouts, hostgroups, id_list_func, id_get_func)
2013-06-18 02:58:40 +02:00
return layouts