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
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
32 log.e(msg)
33 self.msg = msg
34
37
38
52
54 return {"members": {}, "periods": {}, "hostgroups": {}, "layouts": {}, "core": {}}
55
60
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
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
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
113
114
115 mods[clazz] = mod
116 return mod
117
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
146
147 self.log.d("warning: instance_check isn't working yet! TRUST_ALL = TRUE")
148
149
150
151
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
187
188
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
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
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
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
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