Package linspector :: Package lib :: Package config :: Module parser
[hide private]
[frames] | no frames]

Source Code for Module linspector.lib.config.parser

  1  from os.path import isfile 
  2  from os.path import join 
  3  from os import getcwd 
  4  import json 
  5  import sys 
  6  import imp 
  7  from layouts import Layout 
  8  from hostgroups import HostGroup 
  9  from members import Member 
 10  from periods import CronPeriod, DatePeriod, IntervalPeriod 
 11   
 12  from lib.services.service import Service 
 13  #print id(Service) 
 14  from lib.processors.processor import Processor 
 15  from lib.parsers.parser import Parser 
 16  from lib.tasks.task import  Task 
 17   
 18  MOD_SERVICES     = "services" 
 19  MOD_PROCESSORS   = "processors" 
 20  MOD_PARSERS      = "parsers" 
 21  MOD_TASKS        = "tasks" 
 22   
 23  KEY_LAYOUTS      = "layouts" 
 24  KEY_HOSTGROUPS   = "hostgroups" 
 25  KEY_MEMBERS      = "members" 
 26  KEY_PERIODS      = "periods" 
 27  KEY_CORE         = "core" 
 28   
 29   
30 -class ConfigurationException(Exception):
31 - def __init__(self, msg, log):
32 log.e(msg) 33 self.msg = msg
34
35 - def __str__(self):
36 return repr(self.msg)
37 38
39 -class ConfigParser:
40 - def __init__(self, log):
41 """ 42 initializes a new ConfigParser Object 43 44 :param log: pre configured logger Object to post messages while parsing" 45 """ 46 self.log = log 47 self.hostgroups = {} 48 self.members = {} 49 self.periods = {} 50 self.layouts = {} 51 self._loadedMods = {MOD_SERVICES: {}, MOD_PROCESSORS: {}, MOD_TASKS: {}, MOD_PARSERS: {}}
52
53 - def _create_new_config_dict(self):
54 return {"members": {}, "periods": {}, "hostgroups": {}, "layouts": {}, "core": {}}
55
56 - def create_config(self, config):
57 configDict = self._create_new_config_dict() 58 for layout in config.get_layouts(): 59 layout._to_config_dict(configDict)
60
61 - def _read_json_config(self, configFilename):
62 """ 63 reads the config File and returns a dictionary, while lowering the first keys 64 65 :param configFilename: the path under which the configuration file should be found 66 """ 67 if not isfile(configFilename): 68 msg = "config file not found at " + str(configFilename) 69 raise ConfigurationException(msg, self.log) 70 71 self.configFilename = configFilename 72 73 with open(configFilename) as cfgFile: 74 config = cfgFile.read() 75 76 self.log.i("reading Config: " + configFilename) 77 return json.loads(config)
78
79 - def _create_raw_Object(self, jsonDict, msgName, creator):
80 """ 81 creates an Main object from the configuration, but just parses raw data and hands it to the object 82 83 :param jsonDict: the configuration file part as dict 84 :param msgName: name of object for error message 85 :param creator: function pointer which is taking two arguments: identifier of the object and arguments. 86 :should return an object 87 :return: a list of objects returned by creator 88 """ 89 items = [] 90 for key, val in jsonDict.items(): 91 try: 92 item = creator(key, val) 93 items.append(item) 94 except Exception: 95 self.log.w("ignoring " + msgName + ": " + key + "! reason:") 96 self.log.w(str(Exception)) 97 return items
98
99 - def _load_module(self, clazz, modPart):
100 """ 101 imports and caches a module. 102 103 :param clazz: the filename of the module (i.e email, ping...) 104 :param modPart: the folder of the module. (i.e services, parsers...) 105 :return: the imported/cached module, or throws an error if it couldn't find it 106 """ 107 mods = self._loadedMods[modPart] 108 if clazz in mods: 109 return mods["class"] 110 else: 111 mod = __import__(clazz) 112 #path = join(getcwd(), "lib", modPart, clazz + ".py") 113 #self.log.w(path) 114 #mod = imp.load_source(clazz, path) 115 mods[clazz] = mod 116 return mod
117
118 - def replace_with_import(self, objList, modPart, items_func, class_check):
119 """ 120 replaces configuration dicts with their objects by importing and creating it in the first step. 121 In the second step the original list of json config dicts gets replaced by the loaded objects 122 123 :param objList: the list of objects which is iterated on 124 :param modPart: the folder from the module (i.e tasks, parsers) 125 :param items_func: function to get a pointer on the list of json-config-objects to replace. Takes one argument and 126 :param class_check: currently unsupported 127 """ 128 for obj in objList: 129 repl = [] 130 items = items_func(obj) 131 for clazzItem in items: 132 try: 133 if "class" not in clazzItem: 134 self.log.w("python says class is not in class item!") 135 self.log.w(modPart) 136 self.log.w(clazzItem) 137 self.log.w(clazzItem["class"]) 138 139 clazz = clazzItem["class"] 140 path = "lib/" + modPart 141 sys.path.append(path) 142 mod = self._load_module(clazz, modPart) 143 item = mod.create(clazzItem) 144 repl.append(item) 145 #TODO: activate the crappy classcheck if answer is provided 146 #http://stackoverflow.com/questions/17179440/ 147 self.log.d("warning: instance_check isn't working yet! TRUST_ALL = TRUE") 148 #if class_check(item): 149 # repl.append(item) 150 #else: 151 # self.log.w(" ignoring class " + clazzItem["class"] + "! It does not pass the class check!") 152 except ImportError, err: 153 self.log.w("could not import " + clazz + ": " + str(clazzItem) + "! reason") 154 self.log.w(str(err)) 155 except KeyError, k: 156 self.log.w("Key " + str(k) + " not in classItem " + str(clazzItem)) 157 except Exception, e: 158 self.log.w("Error while replacing class ( " + clazz + " ):" + str(e)) 159 finally: 160 if path in sys.path: 161 del sys.path[sys.path.index(path)] 162 del items[:] 163 items.extend(repl)
164
165 - def replace_pointer(self, objectList, replObjectList, id_list_func, id_get_func):
166 """ 167 replaces objects from the config by ids. 168 169 :param objectList: the list of objects to be iterated on 170 :param replObjectList: the list of objects to replace 171 :param id_list_func: function taking one argument as object and should return a list of config ids to replace 172 :param id_get_func: function taking one config-object as argument and should return the config id to compare 173 """ 174 for obj in objectList: 175 replacements = [] 176 idList = id_list_func(obj) 177 for id in idList: 178 repl = [o for o in replObjectList if id == id_get_func(o)] 179 if len(repl) == 1: 180 replacements.append(repl[0]) 181 182 del idList[:] 183 idList.extend(replacements)
184
185 - def parse_config(self, configFilename):
186 pass
187 188
189 -def parsePeriodList(name, values):
190 if "date" in values: 191 return DatePeriod(name, **values) 192 193 comp = ["weeks", "days", "hours", "minutes", "seconds", "start_date"] 194 if len([i for i in comp if i in values]) > 0 : 195 return IntervalPeriod(name, **values) 196 197 comp = ["year", "month", "day", "week", "day_of_week", "hour", "minute", "second"] 198 if len([i for i in comp if i in values]) > 0 : 199 return CronPeriod(name, **values) 200 else: 201 raise ConfigurationException("could not determine correct Period(" + repr(values)+").")
202 203
204 -class FullConfigParser(ConfigParser):
205 - def parse_config(self, configFilename):
206 """ 207 parses the json configuration and returns a list of layouts, 208 which contains all necessary information of the config file. 209 parses the full config 210 Parsing will be done in 3 steps: 211 1. get raw Config Objects by just passing the values defined inside the config 212 2. replace references by objects, import services, tasks, parsers and processors 213 3. do sanity checks 214 215 :param configFilename: the configuration file to parse 216 """ 217 self.jsonDict = self._read_json_config(configFilename) 218 219 # first step 220 creator = lambda name, values: Layout(name,**values) 221 layouts = self._create_raw_Object(self.jsonDict[KEY_LAYOUTS], "Layout", creator) 222 223 creator = lambda name, values: Member(name, **values) 224 members = self._create_raw_Object(self.jsonDict[KEY_MEMBERS], "Member", creator) 225 226 creator = lambda name, values: HostGroup(name, **values) 227 hostgroups = self._create_raw_Object(self.jsonDict[KEY_HOSTGROUPS], "Hostgroup", creator) 228 229 creator = parsePeriodList 230 periods = self._create_raw_Object(self.jsonDict[KEY_PERIODS], "Period", creator) 231 232 #2. import and replace 233 items_func = lambda hostgroup: hostgroup.get_services() 234 class_check = lambda service: isinstance(service, Service) 235 self.replace_with_import(hostgroups, MOD_SERVICES, items_func, class_check) 236 237 items_func = lambda hostgroup: hostgroup.get_processors() 238 class_check = lambda processor: isinstance(processor, Processor) 239 self.replace_with_import(hostgroups, MOD_PROCESSORS, items_func, class_check) 240 241 services = [] 242 for hg in hostgroups: 243 services.extend(hg.get_services()) 244 245 items_func = lambda service: service.get_parser() 246 class_check = lambda parser: isinstance(parser, Parser) 247 self.replace_with_import(services, MOD_PARSERS, items_func, class_check) 248 249 items_func = lambda member: member.get_tasks() 250 class_check = lambda task: isinstance(task, Task) 251 self.replace_with_import(members, MOD_TASKS, items_func, class_check) 252 253 #replace object pointer 254 id_list_func = lambda hostgroup: hostgroup.get_members() 255 id_get_func = lambda member: member.id 256 self.replace_pointer(hostgroups, members, id_list_func, id_get_func) 257 258 id_list_func = lambda service: service.get_periods() 259 id_get_func = lambda period: period.get_name() 260 self.replace_pointer(services, periods, id_list_func, id_get_func) 261 262 id_list_func = lambda layout: layout.get_hostgroups() 263 id_get_func = lambda hostgroup: hostgroup.get_name() 264 self.replace_pointer(layouts, hostgroups, id_list_func, id_get_func) 265 266 return layouts
267