Clean : (Grégory Starck) clean of some getattr code, bis.
[shinken.git] / shinken / contact.py
blob970c825c14a72267508d4fce49ed804d633fb6b4
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.item import Item, Items
23 from shinken.util import to_split, to_bool, strip_and_uniq
24 from shinken.property import UnusedProp, BoolProp, IntegerProp, FloatProp, CharProp, StringProp, ListProp
25 from shinken.log import logger
27 class Contact(Item):
28 id = 1#0 is always special in database, so we do not take risk here
29 my_type = 'contact'
31 properties={
32 'contact_name' : StringProp(fill_brok=['full_status']),
33 'alias' : StringProp(default='none', fill_brok=['full_status']),
34 'contactgroups' : StringProp(default='', fill_brok=['full_status']),
35 'host_notifications_enabled' : BoolProp(default='1', fill_brok=['full_status']),
36 'service_notifications_enabled' : BoolProp(default='1', fill_brok=['full_status']),
37 'host_notification_period' : StringProp(fill_brok=['full_status']),
38 'service_notification_period' : StringProp(fill_brok=['full_status']),
39 'host_notification_options' : ListProp(fill_brok=['full_status']),
40 'service_notification_options' : ListProp(fill_brok=['full_status']),
41 'host_notification_commands' : StringProp(fill_brok=['full_status']),
42 'service_notification_commands' : StringProp(fill_brok=['full_status']),
43 'min_criticity' : IntegerProp(default = '0', fill_brok=['full_status']),
44 'email' : StringProp(default='none', fill_brok=['full_status']),
45 'pager' : StringProp(default='none', fill_brok=['full_status']),
46 'address1' : StringProp(default='none', fill_brok=['full_status']),
47 'address2' : StringProp(default='none', fill_brok=['full_status']),
48 'address3' : StringProp(default='none', fill_brok=['full_status']),
49 'address4' : StringProp(default='none', fill_brok=['full_status']),
50 'address5' : StringProp(default='none', fill_brok=['full_status']),
51 'address6' : StringProp(default='none', fill_brok=['full_status']),
52 'can_submit_commands' : BoolProp(default='0', fill_brok=['full_status']),
53 'retain_status_information' : BoolProp(default='1', fill_brok=['full_status']),
54 'notificationways' : StringProp(default=''),
57 running_properties = {
58 #All errors and warning raised during the configuration parsing
59 #and taht will raised real warning/errors during the is_correct
60 'configuration_warnings' : ListProp(default=[]),
61 'configuration_errors' : ListProp(default=[]),
62 'downtimes': StringProp(
63 default=[],
64 fill_brok=['full_status'],
65 retention=True),
69 macros = {
70 'CONTACTNAME' : 'contact_name',
71 'CONTACTALIAS' : 'alias',
72 'CONTACTEMAIL' : 'email',
73 'CONTACTPAGER' : 'pager',
74 'CONTACTADDRESS1' : 'address1',
75 'CONTACTADDRESS2' : 'address2',
76 'CONTACTADDRESS3' : 'address3',
77 'CONTACTADDRESS4' : 'address4',
78 'CONTACTADDRESS5' : 'address5',
79 'CONTACTADDRESS6' : 'address6',
80 'CONTACTGROUPNAME' : 'get_groupname',
81 'CONTACTGROUPNAMES' : 'get_groupnames'
85 #For debugging purpose only (nice name)
86 def get_name(self):
87 return self.contact_name
90 #Search for notification_options with state and if t is
91 #in service_notification_period
92 def want_service_notification(self, t, state, type, criticity):
93 if not self.service_notifications_enabled:
94 return False
96 # If we are in downtime, we do nto want notification
97 for dt in self.downtimes:
98 if dt.is_in_effect:
99 return False
101 #Now the rest is for sub notificationways. If one is OK, we are ok
102 for nw in self.notificationways:
103 nw_b = nw.want_service_notification(t, state, type, criticity)
104 if nw_b:
105 return True
107 #Oh... no one is ok for it? so no, sorry
108 return False
111 #Search for notification_options with state and if t is in
112 #host_notification_period
113 def want_host_notification(self, t, state, type, criticity):
114 if not self.host_notifications_enabled:
115 return False
117 # If we are in downtime, we do nto want notification
118 for dt in self.downtimes:
119 if dt.is_in_effect:
120 return False
122 #Now it's all for sub notificationways. If one is OK, we are OK
123 for nw in self.notificationways:
124 nw_b = nw.want_host_notification(t, state, type, criticity)
125 if nw_b:
126 return True
128 #Oh, nobody..so NO :)
129 return False
132 #Useless function from now
133 def clean(self):
134 pass
137 #Call to get our commands to launch a Notification
138 def get_notification_commands(self, type):
139 r = []
140 #service_notification_commands for service
141 notif_commands_prop = type+'_notification_commands'
142 for nw in self.notificationways:
143 r.extend(getattr(nw, notif_commands_prop))
144 return r
148 #Check is required prop are set:
149 #contacts OR contactgroups is need
150 def is_correct(self):
151 state = True #guilty or not? :)
152 cls = self.__class__
154 #All of the above are checks in the notificationways part
155 special_properties = ['service_notification_commands', 'host_notification_commands', \
156 'service_notification_period', 'host_notification_period', \
157 'service_notification_options', 'host_notification_options', \
158 'host_notification_commands', 'contact_name']
160 for prop in cls.properties:
161 if prop not in special_properties:
162 if not hasattr(self, prop) and cls.properties[prop].required:
163 print self.get_name(), " : I do not have", prop
164 state = False #Bad boy...
166 #There is a case where there is no nw : when there is not special_prop defined
167 #at all!!
168 if self.notificationways == []:
169 for p in special_properties:
170 print self.get_name()," : I'm missing the property %s" % p
171 state = False
173 if hasattr(self, 'contact_name'):
174 for c in cls.illegal_object_name_chars:
175 if c in self.contact_name:
176 logger.log("%s : My contact_name got the caracter %s that is not allowed." % (self.get_name(), c))
177 state = False
178 else:
179 if hasattr(self, 'alias'): #take the alias if we miss the contact_name
180 self.contact_name = self.alias
181 return state
185 # Raise a log entry when a downtime begins
186 # CONTACT DOWNTIME ALERT: test_contact;STARTED; Contact has entered a period of scheduled downtime
187 def raise_enter_downtime_log_entry(self):
188 logger.log("CONTACT DOWNTIME ALERT: %s;STARTED; Contact has entered a period of scheduled downtime" % self.get_name())
191 # Raise a log entry when a downtime has finished
192 # CONTACT DOWNTIME ALERT: test_contact;STOPPED; Contact has exited from a period of scheduled downtime
193 def raise_exit_downtime_log_entry(self):
194 logger.log("CONTACT DOWNTIME ALERT: %s;STOPPED; Contact has exited from a period of scheduled downtime" % self.get_name())
197 # Raise a log entry when a downtime prematurely ends
198 # CONTACT DOWNTIME ALERT: test_contact;CANCELLED; Contact has entered a period of scheduled downtime
199 def raise_cancel_downtime_log_entry(self):
200 logger.log("CONTACT DOWNTIME ALERT: %s;CANCELLED; Scheduled downtime for contact has been cancelled." % self.get_name())
203 class Contacts(Items):
204 name_property = "contact_name"
205 inner_class = Contact
207 def linkify(self, timeperiods, commands, notificationways):
208 self.linkify_with_timeperiods(timeperiods, 'service_notification_period')
209 self.linkify_with_timeperiods(timeperiods, 'host_notification_period')
210 self.linkify_command_list_with_commands(commands, 'service_notification_commands')
211 self.linkify_command_list_with_commands(commands, 'host_notification_commands')
212 self.linkify_with_notificationways(notificationways)
214 #We've got a notificationways property with , separated contacts names
215 #and we want have a list of NotificationWay
216 def linkify_with_notificationways(self, notificationways):
217 for i in self:
218 if not hasattr(i, 'notificationways'): continue
219 new_notificationways = []
220 for nw_name in strip_and_uniq(i.notificationways.split(',')):
221 nw = notificationways.find_by_name(nw_name)
222 if nw != None:
223 new_notificationways.append(nw)
224 else: #TODO: What?
225 pass
226 #Get the list, but first make elements uniq
227 i.notificationways = list(set(new_notificationways))
231 #We look for contacts property in contacts and
232 def explode(self, contactgroups, notificationways):
233 #Contactgroups property need to be fullfill for got the informations
234 self.apply_partial_inheritance('contactgroups')
236 #Register ourself into the contactsgroups we are in
237 for c in self:
238 if c.is_tpl() or not (hasattr(c, 'contact_name') and hasattr(c, 'contactgroups')):
239 continue
240 for cg in c.contactgroups.split(','):
241 contactgroups.add_member(c.contact_name, cg.strip())
243 #Now create a notification way with the simple parameter of the
244 #contacts
245 simple_way_parameters = ['service_notification_period', 'host_notification_period', \
246 'service_notification_options', 'host_notification_options', \
247 'service_notification_commands', 'host_notification_commands', \
248 'min_criticity']
249 for c in self:
250 if not c.is_tpl():
251 need_notificationway = False
252 params = {}
253 for p in simple_way_parameters:
254 if hasattr(c, p):
255 need_notificationway = True
256 params[p] = getattr(c, p)
258 if need_notificationway:
259 #print "Create notif way with", params
260 cname = getattr(c, 'contact_name', getattr(c, 'alias', ''))
261 nw_name = cname+'_inner_notificationway'
262 notificationways.new_inner_member(nw_name, params)
264 if not hasattr(c, 'notificationways'):
265 c.notificationways = nw_name
266 else:
267 c.notificationways = c.notificationways + ',' +nw_name