2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
5 # Gregory Starck, g.starck@gmail.com
6 # Hartmut Goebel, h.goebel@goebel-consult.de
8 #This file is part of Shinken.
10 #Shinken is free software: you can redistribute it and/or modify
11 #it under the terms of the GNU Affero General Public License as published by
12 #the Free Software Foundation, either version 3 of the License, or
13 #(at your option) any later version.
15 #Shinken is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 #GNU Affero General Public License for more details.
20 #You should have received a copy of the GNU Affero General Public License
21 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
24 from shinken
.objects
.itemgroup
import Itemgroup
, Itemgroups
26 from shinken
.property import BoolProp
, IntegerProp
, StringProp
28 #It change from hostgroup Class because there is no members
29 #propertie, just the realm_members that we rewrite on it.
32 class Realm(Itemgroup
):
33 id = 1 #0 is always a little bit special... like in database
37 'id': IntegerProp(default
=0, fill_brok
=['full_status']),
38 'realm_name': StringProp (fill_brok
=['full_status']),
39 'realm_members': StringProp (default
=''),#No status_broker_name because it put hosts, not host_name
40 'higher_realms': StringProp (default
=''),
41 'default': BoolProp (default
='0'),
42 #'alias': {'required': True, 'fill_brok' : ['full_status']},
43 #'notes': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
44 #'notes_url': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
45 #'action_url': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
49 'REALMNAME': 'realm_name',
50 'REALMMEMBERS': 'members',
55 return self
.realm_name
59 return self
.realm_members
62 def add_string_member(self
, member
):
63 self
.realm_members
+= ','+member
66 def get_realm_members(self
):
67 if self
.has('realm_members'):
68 return [r
.strip() for r
in self
.realm_members
.split(',')]
73 #Use to make pyton properties
74 #TODO : change itemgroup function pythonize?
77 for prop
, tab
in cls
.properties
.items():
79 old_val
= getattr(self
, prop
)
80 new_val
= tab
.pythonize(old_val
)
81 #print "Changing ", old_val, "by", new_val
82 setattr(self
, prop
, new_val
)
83 except AttributeError , exp
:
84 #print self.get_name(), ' : ', exp
85 pass # Will be catch at the is_correct moment
88 #We fillfull properties with template ones if need
89 #Because hostgroup we call may not have it's members
90 #we call get_hosts_by_explosion on it
91 def get_realms_by_explosion(self
, realms
):
92 #First we tag the hg so it will not be explode
93 #if a son of it already call it
94 self
.already_explode
= True
96 #Now the recursiv part
97 #rec_tag is set to False avery HG we explode
98 #so if True here, it must be a loop in HG
101 print "Error : we've got a loop in realm definition", self
.get_name()
102 if self
.has('members'):
106 #Ok, not a loop, we tag it and continue
109 p_mbrs
= self
.get_realm_members()
111 p
= realms
.find_by_name(p_mbr
.strip())
113 value
= p
.get_realms_by_explosion(realms
)
114 if value
is not None:
115 self
.add_string_member(value
)
117 if self
.has('members'):
123 def get_schedulers(self
):
125 for s
in self
.schedulers
:
130 def get_all_schedulers(self
):
132 for s
in self
.schedulers
:
134 for p
in self
.realm_members
:
135 tmps
= p
.get_all_schedulers()
141 def get_pollers(self
):
143 for p
in self
.pollers
:
148 def get_all_subs_pollers(self
):
149 r
= self
.get_pollers()
150 for p
in self
.realm_members
:
151 tmps
= p
.get_all_subs_pollers()
159 def get_reactionners(self
):
161 for p
in self
.reactionners
:
166 def get_all_subs_reactionners(self
):
167 r
= self
.get_reactionners()
168 for p
in self
.realm_members
:
169 tmps
= p
.get_all_subs_reactionners()
175 def count_reactionners(self
):
176 self
.nb_reactionners
= 0
177 for reactionner
in self
.reactionners
:
178 if not reactionner
.spare
:
179 self
.nb_reactionners
+= 1
180 for realm
in self
.higher_realms
:
181 for reactionner
in realm
.reactionners
:
182 if not reactionner
.spare
and reactionner
.manage_sub_realms
:
183 self
.nb_reactionners
+= 1
184 print self
.get_name(),"Count reactionners :", self
.nb_reactionners
187 def fill_potential_reactionners(self
):
188 self
.potential_reactionners
= []
189 for reactionner
in self
.reactionners
:
190 self
.potential_reactionners
.append(reactionner
)
191 for realm
in self
.higher_realms
:
192 for reactionner
in realm
.reactionners
:
193 if reactionner
.manage_sub_realms
:
194 self
.potential_reactionners
.append(reactionner
)
195 print self
.get_name(),"Add potential reactionners :", len(self
.potential_reactionners
)
198 def count_pollers(self
):
200 for poller
in self
.pollers
:
203 for realm
in self
.higher_realms
:
204 for poller
in realm
.pollers
:
205 if not poller
.spare
and poller
.manage_sub_realms
:
207 print self
.get_name(),"Count pollers :", self
.nb_pollers
210 def fill_potential_pollers(self
):
211 self
.potential_pollers
= []
212 for poller
in self
.pollers
:
213 self
.potential_pollers
.append(poller
)
214 for realm
in self
.higher_realms
:
215 for poller
in realm
.pollers
:
216 if poller
.manage_sub_realms
:
217 self
.potential_pollers
.append(poller
)
218 print self
.get_name(),"Add potential pollers :", len(self
.potential_pollers
)
221 def count_brokers(self
):
223 for broker
in self
.brokers
:
226 for realm
in self
.higher_realms
:
227 for broker
in realm
.brokers
:
228 if not broker
.spare
and broker
.manage_sub_realms
:
230 print self
.get_name(),"Count brokers :", self
.nb_brokers
233 def fill_potential_brokers(self
):
234 self
.potential_brokers
= []
235 for broker
in self
.brokers
:
236 self
.potential_brokers
.append(broker
)
237 for realm
in self
.higher_realms
:
238 for broker
in realm
.brokers
:
239 if broker
.manage_sub_realms
:
240 self
.potential_brokers
.append(broker
)
241 print self
.get_name(),"Add potential brokers :", len(self
.potential_brokers
)
244 #Return the list of satellites of a certain type
245 #like reactionner -> self.reactionners
246 def get_satellties_by_type(self
, type):
247 if hasattr(self
, type+'s'):
248 return getattr(self
, type+'s')
250 print "Sorry I do not have this kind of satellites : ", type
254 #Return the list of potentials satellites of a certain type
255 #like reactionner -> self.potential_reactionners
256 def get_potential_satellites_by_type(self
, type):
257 if hasattr(self
, 'potential_'+type+'s'):
258 return getattr(self
, 'potential_'+type+'s')
260 print "Sorry I do not have this kind of satellites : ", type
264 #Return the list of potentials satellites of a certain type
265 #like reactionner -> self.nb_reactionners
266 def get_nb_of_must_have_satellites(self
, type):
267 if hasattr(self
, 'nb_'+type+'s'):
268 return getattr(self
, 'nb_'+type+'s')
270 print "Sorry I do not have this kind of satellites : ", type
274 #Fill dict of realms for managing the satellites confs
275 def prepare_for_satellites_conf(self
):
276 self
.to_satellites
= {}
277 self
.to_satellites
['reactionner'] = {}
278 self
.to_satellites
['poller'] = {}
279 self
.to_satellites
['broker'] = {}
281 self
.to_satellites_nb_assigned
= {}
282 self
.to_satellites_nb_assigned
['reactionner'] = {}
283 self
.to_satellites_nb_assigned
['poller'] = {}
284 self
.to_satellites_nb_assigned
['broker'] = {}
286 self
.to_satellites_nb_assigned
= {}
287 self
.to_satellites_nb_assigned
['reactionner'] = {}
288 self
.to_satellites_nb_assigned
['poller'] = {}
289 self
.to_satellites_nb_assigned
['broker'] = {}
291 self
.to_satellites_need_dispatch
= {}
292 self
.to_satellites_need_dispatch
['reactionner'] = {}
293 self
.to_satellites_need_dispatch
['poller'] = {}
294 self
.to_satellites_need_dispatch
['broker'] = {}
296 self
.to_satellites_managed_by
= {}
297 self
.to_satellites_managed_by
['reactionner'] = {}
298 self
.to_satellites_managed_by
['poller'] = {}
299 self
.to_satellites_managed_by
['broker'] = {}
301 self
.count_reactionners()
302 self
.fill_potential_reactionners()
304 self
.fill_potential_pollers()
306 self
.fill_potential_brokers()
309 # TODO: find a better name...
310 # TODO : and if he goes active?
311 def fill_broker_with_poller_reactionner_links(self
, broker
):
312 # First we create/void theses links
313 broker
.cfg
['pollers'] = {}
314 broker
.cfg
['reactionners'] = {}
316 # First our own level
317 for p
in self
.get_pollers():
318 cfg
= p
.give_satellite_cfg()
319 broker
.cfg
['pollers'][p
.id] = cfg
321 for r
in self
.get_reactionners():
322 cfg
= r
.give_satellite_cfg()
323 broker
.cfg
['reactionners'][r
.id] = cfg
325 # Then sub if we must to it
326 if broker
.manage_sub_realms
:
328 for p
in self
.get_all_subs_pollers():
329 cfg
= p
.give_satellite_cfg()
330 broker
.cfg
['pollers'][p
.id] = cfg
333 for r
in self
.get_all_subs_reactionners():
334 cfg
= r
.give_satellite_cfg()
335 broker
.cfg
['reactionners'][r
.id] = cfg
337 print "***** Broker Me %s got a poller/reactionner link : %s and %s" % (broker
.get_name(), broker
.cfg
['pollers'], broker
.cfg
['reactionners'])
340 #TODO: find a better name...
341 #TODO : and if he goes active?
342 def fill_broker_with_scheduler_links(self
, broker
):
343 print "DBG: filling broker", broker
.get_name()
344 #First we create/void theses links
345 broker
.cfg
['schedulers'] = {}
346 #broker.cfg['reactionners'] = {}
349 for s
in self
.get_schedulers():
350 if s
.conf
is not None:
351 cfg
= s
.give_satellite_cfg()
352 broker
.cfg
['schedulers'][s
.conf
.id] = cfg
354 #Then sub if we must to it
355 if broker
.manage_sub_realms
:
356 print "All schedulers", self
.get_all_schedulers()
357 for s
in self
.get_all_schedulers():
358 if s
.conf
is not None:
359 cfg
= s
.give_satellite_cfg()
360 broker
.cfg
['schedulers'][s
.conf
.id] = cfg
362 print "FUCK, not managing it!"
364 print "***** Broker Me %s got schedulers links : %s" % (broker
.get_name(), broker
.cfg
['schedulers'])
367 # Get a conf package of satellites links that can be useful for
369 def get_satellites_links_for_scheduler(self
):
372 # First we create/void theses links
374 cfg
['reactionners'] = {}
376 # First our own level
377 for p
in self
.get_pollers():
378 c
= p
.give_satellite_cfg()
379 cfg
['pollers'][p
.id] = c
381 for r
in self
.get_reactionners():
382 c
= r
.give_satellite_cfg()
383 cfg
['reactionners'][r
.id] = c
385 print "***** Preparing a satellites conf for a scheduler", cfg
390 class Realms(Itemgroups
):
391 name_property
= "realm_name" # is used for finding hostgroups
396 return len(self
.itemgroups
)
399 def get_members_by_name(self
, pname
):
400 id = self
.find_id_by_name(pname
)
403 return self
.itemgroups
[id].get_realms()
407 self
.linkify_p_by_p()
408 #prepare list of satallites and confs
409 for p
in self
.itemgroups
.values():
418 #We just search for each realm the others realms
419 #and replace the name by the realm
420 def linkify_p_by_p(self
):
421 for p
in self
.itemgroups
.values():
422 mbrs
= p
.get_realm_members()
423 #The new member list, in id
426 new_mbr
= self
.find_by_name(mbr
)
427 if new_mbr
is not None:
428 new_mbrs
.append(new_mbr
)
429 #We find the id, we remplace the names
430 p
.realm_members
= new_mbrs
431 print "For realm", p
.get_name()
432 for m
in p
.realm_members
:
433 print "Member:", m
.get_name()
435 #Now put higher realm in sub realms
437 for p
in self
.itemgroups
.values():
440 for p
in self
.itemgroups
.values():
441 for sub_p
in p
.realm_members
:
442 sub_p
.higher_realms
.append(p
)
445 #Use to fill members with hostgroup_members
447 #We do not want a same hg to be explode again and again
449 for tmp_p
in self
.itemgroups
.values():
450 tmp_p
.already_explode
= False
451 for p
in self
.itemgroups
.values():
452 if p
.has('realm_members') and not p
.already_explode
:
453 #get_hosts_by_explosion is a recursive
454 #function, so we must tag hg so we do not loop
455 for tmp_p
in self
.itemgroups
.values():
456 tmp_p
.rec_tag
= False
457 p
.get_realms_by_explosion(self
)
460 for tmp_p
in self
.itemgroups
.values():
461 if hasattr(tmp_p
, 'rec_tag'):
463 del tmp_p
.already_explode
466 def get_default(self
):