PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/shinken/objects/realm.py

https://github.com/sduchesneau/shinken
Python | 431 lines | 394 code | 7 blank | 30 comment | 3 complexity | f469c5e34b4b521ab72b142934b946ec MD5 | raw file
  1. #!/usr/bin/env python
  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
  7. #
  8. #This file is part of Shinken.
  9. #
  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.
  14. #
  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.
  19. #
  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/>.
  22. import copy
  23. from itemgroup import Itemgroup, Itemgroups
  24. from shinken.property import BoolProp, IntegerProp, StringProp
  25. from shinken.log import logger
  26. #It change from hostgroup Class because there is no members
  27. #propertie, just the realm_members that we rewrite on it.
  28. class Realm(Itemgroup):
  29. id = 1 #0 is always a little bit special... like in database
  30. my_type = 'realm'
  31. properties = Itemgroup.properties.copy()
  32. properties.update({
  33. 'id': IntegerProp(default=0, fill_brok=['full_status']),
  34. 'realm_name': StringProp (fill_brok=['full_status']),
  35. 'realm_members': StringProp (default=''),#No status_broker_name because it put hosts, not host_name
  36. 'higher_realms': StringProp (default=''),
  37. 'default': BoolProp (default='0'),
  38. #'alias': {'required': True, 'fill_brok' : ['full_status']},
  39. #'notes': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
  40. #'notes_url': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
  41. #'action_url': {'required': False, 'default':'', 'fill_brok' : ['full_status']},
  42. })
  43. macros = {
  44. 'REALMNAME': 'realm_name',
  45. 'REALMMEMBERS': 'members',
  46. }
  47. def get_name(self):
  48. return self.realm_name
  49. def get_realms(self):
  50. return self.realm_members
  51. def add_string_member(self, member):
  52. self.realm_members += ','+member
  53. def get_realm_members(self):
  54. if self.has('realm_members'):
  55. return [r.strip() for r in self.realm_members.split(',')]
  56. else:
  57. return []
  58. # Use to make pyton properties
  59. # TODO : change itemgroup function pythonize?
  60. def pythonize(self):
  61. cls = self.__class__
  62. for prop, tab in cls.properties.items():
  63. try:
  64. old_val = getattr(self, prop)
  65. new_val = tab.pythonize(old_val)
  66. #print "Changing ", old_val, "by", new_val
  67. setattr(self, prop, new_val)
  68. except AttributeError , exp:
  69. pass # Will be catch at the is_correct moment
  70. # We fillfull properties with template ones if need
  71. # Because hostgroup we call may not have it's members
  72. # we call get_hosts_by_explosion on it
  73. def get_realms_by_explosion(self, realms):
  74. # First we tag the hg so it will not be explode
  75. # if a son of it already call it
  76. self.already_explode = True
  77. # Now the recursiv part
  78. # rec_tag is set to False avery HG we explode
  79. # so if True here, it must be a loop in HG
  80. # calls... not GOOD!
  81. if self.rec_tag:
  82. err = "Error : we've got a loop in realm definition %s" % self.get_name()
  83. self.configuration_errors.append(err)
  84. if self.has('members'):
  85. return self.members
  86. else:
  87. return ''
  88. #Ok, not a loop, we tag it and continue
  89. self.rec_tag = True
  90. p_mbrs = self.get_realm_members()
  91. for p_mbr in p_mbrs:
  92. p = realms.find_by_name(p_mbr.strip())
  93. if p is not None:
  94. value = p.get_realms_by_explosion(realms)
  95. if value is not None:
  96. self.add_string_member(value)
  97. if self.has('members'):
  98. return self.members
  99. else:
  100. return ''
  101. def get_all_subs_pollers(self):
  102. r = copy.copy(self.pollers)
  103. for p in self.realm_members:
  104. tmps = p.get_all_subs_pollers()
  105. for s in tmps:
  106. r.append(s)
  107. return r
  108. def get_all_subs_reactionners(self):
  109. r = copy.copy(self.reactionners)
  110. for p in self.realm_members:
  111. tmps = p.get_all_subs_reactionners()
  112. for s in tmps:
  113. r.append(s)
  114. return r
  115. def count_reactionners(self):
  116. self.nb_reactionners = 0
  117. for reactionner in self.reactionners:
  118. if not reactionner.spare:
  119. self.nb_reactionners += 1
  120. for realm in self.higher_realms:
  121. for reactionner in realm.reactionners:
  122. if not reactionner.spare and reactionner.manage_sub_realms:
  123. self.nb_reactionners += 1
  124. def fill_potential_reactionners(self):
  125. self.potential_reactionners = []
  126. for reactionner in self.reactionners:
  127. self.potential_reactionners.append(reactionner)
  128. for realm in self.higher_realms:
  129. for reactionner in realm.reactionners:
  130. if reactionner.manage_sub_realms:
  131. self.potential_reactionners.append(reactionner)
  132. def count_pollers(self):
  133. self.nb_pollers = 0
  134. for poller in self.pollers:
  135. if not poller.spare:
  136. self.nb_pollers += 1
  137. for realm in self.higher_realms:
  138. for poller in realm.pollers:
  139. if not poller.spare and poller.manage_sub_realms:
  140. self.nb_pollers += 1
  141. def fill_potential_pollers(self):
  142. self.potential_pollers = []
  143. for poller in self.pollers:
  144. self.potential_pollers.append(poller)
  145. for realm in self.higher_realms:
  146. for poller in realm.pollers:
  147. if poller.manage_sub_realms:
  148. self.potential_pollers.append(poller)
  149. def count_brokers(self):
  150. self.nb_brokers = 0
  151. for broker in self.brokers:
  152. if not broker.spare:
  153. self.nb_brokers += 1
  154. for realm in self.higher_realms:
  155. for broker in realm.brokers:
  156. if not broker.spare and broker.manage_sub_realms:
  157. self.nb_brokers += 1
  158. def fill_potential_brokers(self):
  159. self.potential_brokers = []
  160. for broker in self.brokers:
  161. self.potential_brokers.append(broker)
  162. for realm in self.higher_realms:
  163. for broker in realm.brokers:
  164. if broker.manage_sub_realms:
  165. self.potential_brokers.append(broker)
  166. def count_receivers(self):
  167. self.nb_receivers = 0
  168. for receiver in self.receivers:
  169. if not receiver.spare:
  170. self.nb_receivers += 1
  171. for realm in self.higher_realms:
  172. for receiver in realm.receivers:
  173. if not receiver.spare and receiver.manage_sub_realms:
  174. self.nb_receivers += 1
  175. def fill_potential_receivers(self):
  176. self.potential_receivers = []
  177. for broker in self.receivers:
  178. self.potential_receivers.append(broker)
  179. for realm in self.higher_realms:
  180. for broker in realm.receivers:
  181. if broker.manage_sub_realms:
  182. self.potential_receivers.append(broker)
  183. #Return the list of satellites of a certain type
  184. #like reactionner -> self.reactionners
  185. def get_satellties_by_type(self, type):
  186. if hasattr(self, type+'s'):
  187. return getattr(self, type+'s')
  188. else:
  189. print "Sorry I do not have this kind of satellites : ", type
  190. return []
  191. #Return the list of potentials satellites of a certain type
  192. #like reactionner -> self.potential_reactionners
  193. def get_potential_satellites_by_type(self, type):
  194. if hasattr(self, 'potential_'+type+'s'):
  195. return getattr(self, 'potential_'+type+'s')
  196. else:
  197. print "Sorry I do not have this kind of satellites : ", type
  198. return []
  199. #Return the list of potentials satellites of a certain type
  200. #like reactionner -> self.nb_reactionners
  201. def get_nb_of_must_have_satellites(self, type):
  202. if hasattr(self, 'nb_'+type+'s'):
  203. return getattr(self, 'nb_'+type+'s')
  204. else:
  205. print "Sorry I do not have this kind of satellites : ", type
  206. return 0
  207. #Fill dict of realms for managing the satellites confs
  208. def prepare_for_satellites_conf(self):
  209. self.to_satellites = {}
  210. self.to_satellites['reactionner'] = {}
  211. self.to_satellites['poller'] = {}
  212. self.to_satellites['broker'] = {}
  213. self.to_satellites['receiver'] = {}
  214. self.to_satellites_need_dispatch = {}
  215. self.to_satellites_need_dispatch['reactionner'] = {}
  216. self.to_satellites_need_dispatch['poller'] = {}
  217. self.to_satellites_need_dispatch['broker'] = {}
  218. self.to_satellites_need_dispatch['receiver'] = {}
  219. self.to_satellites_managed_by = {}
  220. self.to_satellites_managed_by['reactionner'] = {}
  221. self.to_satellites_managed_by['poller'] = {}
  222. self.to_satellites_managed_by['broker'] = {}
  223. self.to_satellites_managed_by['receiver'] = {}
  224. self.count_reactionners()
  225. self.fill_potential_reactionners()
  226. self.count_pollers()
  227. self.fill_potential_pollers()
  228. self.count_brokers()
  229. self.fill_potential_brokers()
  230. self.count_receivers()
  231. self.fill_potential_receivers()
  232. s = "%s : (in/potential) (schedulers:%d) (pollers:%d/%d) (reactionners:%d/%d) (brokers:%d/%d) (receivers:%d/%d)" % \
  233. (self.get_name(),
  234. len(self.schedulers),
  235. self.nb_pollers, len(self.potential_pollers),
  236. self.nb_reactionners, len(self.potential_reactionners),
  237. self.nb_brokers, len(self.potential_brokers),
  238. self.nb_receivers, len(self.potential_receivers)
  239. )
  240. logger.log(s)
  241. # TODO: find a better name...
  242. # TODO : and if he goes active?
  243. def fill_broker_with_poller_reactionner_links(self, broker):
  244. # First we create/void theses links
  245. broker.cfg['pollers'] = {}
  246. broker.cfg['reactionners'] = {}
  247. # First our own level
  248. for p in self.pollers:
  249. cfg = p.give_satellite_cfg()
  250. broker.cfg['pollers'][p.id] = cfg
  251. for r in self.reactionners:
  252. cfg = r.give_satellite_cfg()
  253. broker.cfg['reactionners'][r.id] = cfg
  254. # Then sub if we must to it
  255. if broker.manage_sub_realms:
  256. # Now pollers
  257. for p in self.get_all_subs_pollers():
  258. cfg = p.give_satellite_cfg()
  259. broker.cfg['pollers'][p.id] = cfg
  260. # Now reactionners
  261. for r in self.get_all_subs_reactionners():
  262. cfg = r.give_satellite_cfg()
  263. broker.cfg['reactionners'][r.id] = cfg
  264. # Get a conf package of satellites links that can be useful for
  265. # a scheduler
  266. def get_satellites_links_for_scheduler(self):
  267. cfg = {}
  268. # First we create/void theses links
  269. cfg['pollers'] = {}
  270. cfg['reactionners'] = {}
  271. # First our own level
  272. for p in self.pollers:
  273. c = p.give_satellite_cfg()
  274. cfg['pollers'][p.id] = c
  275. for r in self.reactionners:
  276. c = r.give_satellite_cfg()
  277. cfg['reactionners'][r.id] = c
  278. #print "***** Preparing a satellites conf for a scheduler", cfg
  279. return cfg
  280. class Realms(Itemgroups):
  281. name_property = "realm_name" # is used for finding hostgroups
  282. inner_class = Realm
  283. def get_members_by_name(self, pname):
  284. realm = self.find_by_name(pname)
  285. if realm is None:
  286. return []
  287. return realm.get_realms()
  288. def linkify(self):
  289. self.linkify_p_by_p()
  290. # prepare list of satellites and confs
  291. for p in self:
  292. p.pollers = []
  293. p.schedulers = []
  294. p.reactionners = []
  295. p.brokers = []
  296. p.receivers = []
  297. p.packs = []
  298. p.confs = {}
  299. #We just search for each realm the others realms
  300. #and replace the name by the realm
  301. def linkify_p_by_p(self):
  302. for p in self.items.values():
  303. mbrs = p.get_realm_members()
  304. #The new member list, in id
  305. new_mbrs = []
  306. for mbr in mbrs:
  307. new_mbr = self.find_by_name(mbr)
  308. if new_mbr is not None:
  309. new_mbrs.append(new_mbr)
  310. #We find the id, we remplace the names
  311. p.realm_members = new_mbrs
  312. #Now put higher realm in sub realms
  313. #So after they can
  314. for p in self.items.values():
  315. p.higher_realms = []
  316. for p in self.items.values():
  317. for sub_p in p.realm_members:
  318. sub_p.higher_realms.append(p)
  319. #Use to fill members with hostgroup_members
  320. def explode(self):
  321. #We do not want a same hg to be explode again and again
  322. #so we tag it
  323. for tmp_p in self.items.values():
  324. tmp_p.already_explode = False
  325. for p in self:
  326. if p.has('realm_members') and not p.already_explode:
  327. #get_hosts_by_explosion is a recursive
  328. #function, so we must tag hg so we do not loop
  329. for tmp_p in self:
  330. tmp_p.rec_tag = False
  331. p.get_realms_by_explosion(self)
  332. #We clean the tags
  333. for tmp_p in self.items.values():
  334. if hasattr(tmp_p, 'rec_tag'):
  335. del tmp_p.rec_tag
  336. del tmp_p.already_explode
  337. def get_default(self):
  338. for r in self:
  339. if getattr(r, 'default', False):
  340. return r
  341. return None
  342. def prepare_for_satellites_conf(self):
  343. for r in self:
  344. r.prepare_for_satellites_conf()