*TAG : 0.5 release
[shinken.git] / shinken / realm.py
blob33e12cebeea6b73e1c218db486e10dd9f47286c9
1 #!/usr/bin/env python
2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
6 #This file is part of Shinken.
8 #Shinken is free software: you can redistribute it and/or modify
9 #it under the terms of the GNU Affero General Public License as published by
10 #the Free Software Foundation, either version 3 of the License, or
11 #(at your option) any later version.
13 #Shinken is distributed in the hope that it will be useful,
14 #but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 #GNU Affero General Public License for more details.
18 #You should have received a copy of the GNU Affero General Public License
19 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
22 from shinken.itemgroup import Itemgroup, Itemgroups
23 from shinken.util import to_bool
24 from shinken.property import UnusedProp, BoolProp, IntegerProp, FloatProp, CharProp, StringProp, ListProp
26 #It change from hostgroup Class because there is no members
27 #propertie, just the realm_members that we rewrite on it.
30 class Realm(Itemgroup):
31 id = 1 #0 is always a little bit special... like in database
32 my_type = 'realm'
34 properties={'id': IntegerProp(default=0, fill_brok=['full_status']),
35 'realm_name': StringProp(fill_brok=['full_status']),
36 #'alias': {'required': True, 'fill_brok' : ['full_status']},
37 #'notes': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
38 #'notes_url': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
39 #'action_url': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
40 'realm_members' : StringProp(default=''),#No status_broker_name because it put hosts, not host_name
41 'higher_realms' : StringProp(default=''),
42 'default' : BoolProp(default='0'),
45 macros = {
46 'REALMNAME' : 'realm_name',
47 'REALMMEMBERS' : 'members',
51 def get_name(self):
52 return self.realm_name
55 def get_realms(self):
56 return self.realm_members
59 def add_string_member(self, member):
60 self.realm_members += ','+member
63 def get_realm_members(self):
64 if self.has('realm_members'):
65 return self.realm_members.split(',')
66 else:
67 return []
70 #Use to make pyton properties
71 #TODO : change itemgroup function pythonize?
72 def pythonize(self):
73 cls = self.__class__
74 for prop in cls.properties:
75 try:
76 tab = cls.properties[prop]
77 f = tab.pythonize
78 old_val = getattr(self, prop)
79 new_val = f(old_val)
80 #print "Changing ", old_val, "by", new_val
81 setattr(self, prop, new_val)
82 except AttributeError , exp:
83 #print self.get_name(), ' : ', exp
84 pass # Will be catch at the is_correct moment
87 #We fillfull properties with template ones if need
88 #Because hostgroup we call may not have it's members
89 #we call get_hosts_by_explosion on it
90 def get_realms_by_explosion(self, realms):
91 #First we tag the hg so it will not be explode
92 #if a son of it already call it
93 self.already_explode = True
95 #Now the recursiv part
96 #rec_tag is set to False avery HG we explode
97 #so if True here, it must be a loop in HG
98 #calls... not GOOD!
99 if self.rec_tag:
100 print "Error : we've got a loop in realm definition", self.get_name()
101 if self.has('members'):
102 return self.members
103 else:
104 return ''
105 #Ok, not a loop, we tag it and continue
106 self.rec_tag = True
108 p_mbrs = self.get_realm_members()
109 for p_mbr in p_mbrs:
110 p = realms.find_by_name(p_mbr.strip())
111 if p is not None:
112 value = p.get_realms_by_explosion(realms)
113 if value is not None:
114 self.add_string_member(value)
116 if self.has('members'):
117 return self.members
118 else:
119 return ''
122 def get_schedulers(self):
123 r = []
124 for s in self.schedulers:
125 r.append(s)
126 return r
129 def get_all_schedulers(self):
130 r = []
131 for s in self.schedulers:
132 r.append(s)
133 for p in self.realm_members:
134 tmps = p.get_all_schedulers()
135 for s in tmps:
136 r.append(s)
137 return r
140 def get_pollers(self):
141 r = []
142 for p in self.pollers:
143 r.append(p)
144 return r
147 def get_all_subs_pollers(self):
148 r = self.get_pollers()
149 for p in self.realm_members:
150 tmps = p.get_all_subs_pollers()
151 for s in tmps:
152 r.append(s)
153 return r
158 def get_reactionners(self):
159 r = []
160 for p in self.reactionners:
161 r.append(p)
162 return r
165 def get_all_subs_reactionners(self):
166 r = self.get_reactionners()
167 for p in self.realm_members:
168 tmps = p.get_all_subs_reactionners()
169 for s in tmps:
170 r.append(s)
171 return r
174 def count_reactionners(self):
175 self.nb_reactionners = 0
176 for reactionner in self.reactionners:
177 if not reactionner.spare:
178 self.nb_reactionners += 1
179 for realm in self.higher_realms:
180 for reactionner in realm.reactionners:
181 if not reactionner.spare and reactionner.manage_sub_realms:
182 self.nb_reactionners += 1
183 print self.get_name(),"Count reactionners :", self.nb_reactionners
186 def fill_potential_reactionners(self):
187 self.potential_reactionners = []
188 for reactionner in self.reactionners:
189 self.potential_reactionners.append(reactionner)
190 for realm in self.higher_realms:
191 for reactionner in realm.reactionners:
192 if reactionner.manage_sub_realms:
193 self.potential_reactionners.append(reactionner)
194 print self.get_name(),"Add potential reactionners :", len(self.potential_reactionners)
197 def count_pollers(self):
198 self.nb_pollers = 0
199 for poller in self.pollers:
200 if not poller.spare:
201 self.nb_pollers += 1
202 for realm in self.higher_realms:
203 for poller in realm.pollers:
204 if not poller.spare and poller.manage_sub_realms:
205 self.nb_pollers += 1
206 print self.get_name(),"Count pollers :", self.nb_pollers
209 def fill_potential_pollers(self):
210 self.potential_pollers = []
211 for poller in self.pollers:
212 self.potential_pollers.append(poller)
213 for realm in self.higher_realms:
214 for poller in realm.pollers:
215 if poller.manage_sub_realms:
216 self.potential_pollers.append(poller)
217 print self.get_name(),"Add potential pollers :", len(self.potential_pollers)
220 def count_brokers(self):
221 self.nb_brokers = 0
222 for broker in self.brokers:
223 if not broker.spare:
224 self.nb_brokers += 1
225 for realm in self.higher_realms:
226 for broker in realm.brokers:
227 if not broker.spare and broker.manage_sub_realms:
228 self.nb_brokers += 1
229 print self.get_name(),"Count brokers :", self.nb_brokers
232 def fill_potential_brokers(self):
233 self.potential_brokers = []
234 for broker in self.brokers:
235 self.potential_brokers.append(broker)
236 for realm in self.higher_realms:
237 for broker in realm.brokers:
238 if broker.manage_sub_realms:
239 self.potential_brokers.append(broker)
240 print self.get_name(),"Add potential brokers :", len(self.potential_brokers)
243 #Return the list of satellites of a certain type
244 #like reactionner -> self.reactionners
245 def get_satellties_by_type(self, type):
246 if hasattr(self, type+'s'):
247 return getattr(self, type+'s')
248 else:
249 print "Sorry I do not have this kind of satellites : ", type
250 return []
253 #Return the list of potentials satellites of a certain type
254 #like reactionner -> self.potential_reactionners
255 def get_potential_satellites_by_type(self, type):
256 if hasattr(self, 'potential_'+type+'s'):
257 return getattr(self, 'potential_'+type+'s')
258 else:
259 print "Sorry I do not have this kind of satellites : ", type
260 return []
263 #Return the list of potentials satellites of a certain type
264 #like reactionner -> self.nb_reactionners
265 def get_nb_of_must_have_satellites(self, type):
266 if hasattr(self, 'nb_'+type+'s'):
267 return getattr(self, 'nb_'+type+'s')
268 else:
269 print "Sorry I do not have this kind of satellites : ", type
270 return 0
273 #Fill dict of realms for managing the satellites confs
274 def prepare_for_satellites_conf(self):
275 self.to_satellites = {}
276 self.to_satellites['reactionner'] = {}
277 self.to_satellites['poller'] = {}
278 self.to_satellites['broker'] = {}
280 self.to_satellites_nb_assigned = {}
281 self.to_satellites_nb_assigned['reactionner'] = {}
282 self.to_satellites_nb_assigned['poller'] = {}
283 self.to_satellites_nb_assigned['broker'] = {}
285 self.to_satellites_nb_assigned = {}
286 self.to_satellites_nb_assigned['reactionner'] = {}
287 self.to_satellites_nb_assigned['poller'] = {}
288 self.to_satellites_nb_assigned['broker'] = {}
290 self.to_satellites_need_dispatch = {}
291 self.to_satellites_need_dispatch['reactionner'] = {}
292 self.to_satellites_need_dispatch['poller'] = {}
293 self.to_satellites_need_dispatch['broker'] = {}
295 self.to_satellites_managed_by = {}
296 self.to_satellites_managed_by['reactionner'] = {}
297 self.to_satellites_managed_by['poller'] = {}
298 self.to_satellites_managed_by['broker'] = {}
300 self.count_reactionners()
301 self.fill_potential_reactionners()
302 self.count_pollers()
303 self.fill_potential_pollers()
304 self.count_brokers()
305 self.fill_potential_brokers()
308 #TODO: find a better name...
309 #TODO : and if he goes active?
310 def fill_broker_with_poller_reactionner_links(self, broker):
311 #First we create/void theses links
312 broker.cfg['pollers'] = {}
313 broker.cfg['reactionners'] = {}
315 #First our own level
316 for p in self.get_pollers():
317 cfg = p.give_satellite_cfg()
318 broker.cfg['pollers'][p.id] = cfg
320 for r in self.get_reactionners():
321 cfg = r.give_satellite_cfg()
322 broker.cfg['reactionners'][r.id] = cfg
324 #Then sub if we must to it
325 if broker.manage_sub_realms:
326 #Now pollers
327 for p in self.get_all_subs_pollers():
328 cfg = p.give_satellite_cfg()
329 broker.cfg['pollers'][p.id] = cfg
331 #Now reactionners
332 for r in self.get_all_subs_reactionners():
333 cfg = r.give_satellite_cfg()
334 broker.cfg['reactionners'][r.id] = cfg
336 print "***** Broker Me %s got a poller/reactionner link : %s and %s" % (broker.get_name(), broker.cfg['pollers'], broker.cfg['reactionners'])
339 #TODO: find a better name...
340 #TODO : and if he goes active?
341 def fill_broker_with_scheduler_links(self, broker):
342 print "DBG: filling broker", broker.get_name()
343 #First we create/void theses links
344 broker.cfg['schedulers'] = {}
345 #broker.cfg['reactionners'] = {}
347 #First our own level
348 for s in self.get_schedulers():
349 if s.conf != None:
350 cfg = s.give_satellite_cfg()
351 broker.cfg['schedulers'][s.conf.id] = cfg
353 #Then sub if we must to it
354 if broker.manage_sub_realms:
355 print "All schedulers", self.get_all_schedulers()
356 for s in self.get_all_schedulers():
357 if s.conf != None:
358 cfg = s.give_satellite_cfg()
359 broker.cfg['schedulers'][s.conf.id] = cfg
360 else :
361 print "FUCK, not managing it!"
363 print "***** Broker Me %s got schedulers links : %s" % (broker.get_name(), broker.cfg['schedulers'])
366 class Realms(Itemgroups):
367 name_property = "realm_name" # is used for finding hostgroups
368 inner_class = Realm
371 def __len__(self):
372 return len(self.itemgroups)
375 def get_members_by_name(self, pname):
376 id = self.find_id_by_name(pname)
377 if id == None:
378 return []
379 return self.itemgroups[id].get_realms()
382 def linkify(self):
383 self.linkify_p_by_p()
384 #prepare list of satallites and confs
385 for p in self.itemgroups.values():
386 p.pollers = []
387 p.schedulers = []
388 p.reactionners = []
389 p.brokers = []
390 p.packs = []
391 p.confs = {}
394 #We just search for each realm the others realms
395 #and replace the name by the realm
396 def linkify_p_by_p(self):
397 for p in self.itemgroups.values():
398 mbrs = p.get_realm_members()
399 #The new member list, in id
400 new_mbrs = []
401 for mbr in mbrs:
402 new_mbr = self.find_by_name(mbr)
403 if new_mbr != None:
404 new_mbrs.append(new_mbr)
405 #We find the id, we remplace the names
406 p.realm_members = new_mbrs
407 print "For realm", p.get_name()
408 for m in p.realm_members:
409 print "Member:", m.get_name()
411 #Now put higher realm in sub realms
412 #So after they can
413 for p in self.itemgroups.values():
414 p.higher_realms = []
416 for p in self.itemgroups.values():
417 for sub_p in p.realm_members:
418 sub_p.higher_realms.append(p)
421 #Use to fill members with hostgroup_members
422 def explode(self):
423 #We do not want a same hg to be explode again and again
424 #so we tag it
425 for tmp_p in self.itemgroups.values():
426 tmp_p.already_explode = False
427 for p in self.itemgroups.values():
428 if p.has('realm_members') and not p.already_explode:
429 #get_hosts_by_explosion is a recursive
430 #function, so we must tag hg so we do not loop
431 for tmp_p in self.itemgroups.values():
432 tmp_p.rec_tag = False
433 p.get_realms_by_explosion(self)
435 #We clean the tags
436 for tmp_p in self.itemgroups.values():
437 if hasattr(tmp_p, 'rec_tag'):
438 del tmp_p.rec_tag
439 del tmp_p.already_explode
442 def get_default(self):
443 for r in self:
444 if r.default:
445 return r
446 return None