Fix : (Laurent Guyon) crash in workers.
[shinken.git] / shinken / notification.py
blob85200908cd9e98a32ff974e2a550363e53f197dc
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 import time
24 #Unix and windows do not have the same import
25 #if os.name == 'nt':
26 # import subprocess, datetime, os, time, signal
27 # import ctypes
28 # TerminateProcess = ctypes.windll.kernel32.TerminateProcess
29 #else:
30 # from pexpect import *
32 from action import Action
33 from brok import Brok
34 from shinken.property import UnusedProp, BoolProp, IntegerProp, FloatProp, CharProp, StringProp, ListProp
36 class Notification(Action):
37 #id = 0 #Is in fact in the Action class to be common with Checks and
38 #events handlers
40 properties={
41 'type' : StringProp(default=''),
42 'notification_type': IntegerProp(
43 default=0,
44 fill_brok=['full_status']),
45 'start_time': StringProp(
46 default=0,
47 fill_brok=['full_status']),
48 'end_time': StringProp(
49 default=0,
50 fill_brok=['full_status']),
51 'contact_name': StringProp(
52 default='',
53 fill_brok=['full_status']),
54 'host_name': StringProp(
55 default='',
56 fill_brok=['full_status']),
57 'service_description': StringProp(
58 default='',
59 fill_brok=['full_status']),
60 'reason_type': StringProp(
61 default=0,
62 fill_brok=['full_status']),
63 'state': StringProp(
64 default=0,
65 fill_brok=['full_status']),
66 'output': StringProp(
67 default='',
68 fill_brok=['full_status']),
69 'ack_author': StringProp(
70 default='',
71 fill_brok=['full_status']),
72 'ack_data': StringProp(
73 default='',
74 fill_brok=['full_status']),
75 'escalated': BoolProp(
76 default=False,
77 fill_brok=['full_status']),
78 'contacts_notified': StringProp(
79 default=0,
80 fill_brok=['full_status']),
81 'env': StringProp(
82 default={}),
83 'exit_status' : IntegerProp(default=3),
84 'command_call' : StringProp(default=None),
85 'contact' : StringProp(default=None),
86 '_in_timeout' : BoolProp(default=False),
87 'notif_nb' : IntegerProp(default=0),
88 'status' : StringProp(default='scheduled'),
89 't_to_go' : IntegerProp(default=0),
90 'is_a' : StringProp(default=''),
91 'command' : StringProp(default=''),
92 'host_name' : StringProp(default=''),
93 'sched_id' : IntegerProp(default=0),
94 'timeout' : IntegerProp(default=10),
95 'check_time' : IntegerProp(default=0),
98 macros = {
99 'NOTIFICATIONTYPE' : 'type',
100 'NOTIFICATIONRECIPIENTS' : 'recipients',
101 'NOTIFICATIONISESCALATED' : 'escaladed',
102 'NOTIFICATIONAUTHOR' : 'author',
103 'NOTIFICATIONAUTHORNAME' : 'author_name',
104 'NOTIFICATIONAUTHORALIAS' : 'author_alias',
105 'NOTIFICATIONCOMMENT' : 'comment',
106 'HOSTNOTIFICATIONNUMBER' : 'notif_nb',
107 'HOSTNOTIFICATIONID' : 'id',
108 'SERVICENOTIFICATIONNUMBER' : 'notif_nb',
109 'SERVICENOTIFICATIONID' : 'id'
113 def __init__(self, type , status, command, command_call, ref, contact, t_to_go, \
114 contact_name='', host_name='', service_description='',
115 reason_type=1, state=0, ack_author='', ack_data='', \
116 escalated=False, contacts_notified=0, \
117 start_time=0, end_time=0, notification_type=0, id=None, \
118 notif_nb=1, timeout=10, env={}):
119 self.is_a = 'notification'
120 self.type = type
121 if id == None: #id != None is for copy call only
122 self.id = Action.id
123 Action.id += 1
126 self._in_timeout = False
127 self.timeout = timeout
128 self.status = status
129 self.exit_status = 3
130 self.command = command
131 self.command_call = command_call
132 self.output = None
133 self.ref = ref
134 self.env = env
135 #self.ref_type = ref_type
136 self.t_to_go = t_to_go
137 self.notif_nb = notif_nb
138 self.contact = contact
140 #For brok part
141 self.contact_name = contact_name
142 self.host_name = host_name
143 self.service_description = service_description
144 self.reason_type = reason_type
145 self.state = state
146 self.ack_author = ack_author
147 self.ack_data = ack_data
148 self.escalated = escalated
149 self.contacts_notified = contacts_notified
150 self.start_time = start_time
151 self.end_time = end_time
152 self.notification_type = notification_type
154 #DBG
155 self.creation_time = time.time()
158 #return a copy of the check but just what is important for execution
159 #So we remove the ref and all
160 def copy_shell(self):
161 #We create a dummy check with nothing in it, jsut defaults values
162 new_n = Notification('', '', '', '', '', '', '', id=self.id)
163 only_copy_prop = ['id', 'status', 'command', 't_to_go', 'timeout', 'env']
164 for prop in only_copy_prop:
165 val = getattr(self, prop)
166 setattr(new_n, prop, val)
167 return new_n
171 # def execute(self):
172 # print "Notification %s" % self.command
173 # child = spawn ('/bin/sh -c "%s"' % self.command)
174 # self.status = 'launched'
176 # try:
177 # child.expect_exact(EOF, timeout=5)
178 # self.output = child.before
179 # child.terminate(force=True)
180 # self.exit_status = child.exitstatus
181 # self.status = 'done'
182 # except TIMEOUT:
183 # print "On le kill"
184 # self.status = 'timeout'
185 # child.terminate(force=True)
188 def is_launchable(self, t):
189 return t > self.t_to_go
192 def set_status(self, status):
193 self.status = status
196 def get_status(self):
197 return self.status
200 def get_output(self):
201 return self.output
204 def is_administrative(self):
205 if self.type in ('PROBLEM', 'RECOVERY'):
206 return False
207 else:
208 return True
211 def __str__(self):
212 return "Notification %d status:%s command:%s ref:%s t_to_go:%s" % (self.id, self.status, self.command, self.ref, time.asctime(time.localtime(self.t_to_go)))
213 #return ''#str(self.__dict__)
216 def get_id(self):
217 return self.id
220 def get_return_from(self, n):
221 self.exit_status = n.exit_status
222 #self.output = c.output
223 #self.check_time = c.check_time
224 #self.execution_time = c.execution_time
227 #Fill data with info of item by looking at brok_type
228 #in props of properties or running_propterties
229 def fill_data_brok_from(self, data, brok_type):
230 cls = self.__class__
231 #Now config properties
232 for prop in cls.properties:
233 if hasattr(prop, 'fill_brok'):
234 if brok_type in cls.properties[prop]['fill_brok']:
235 data[prop] = getattr(self, prop)
238 #Get a brok with initial status
239 def get_initial_status_brok(self):
240 data = {'id' : self.id}
242 self.fill_data_brok_from(data, 'full_status')
243 b = Brok('notification_raise', data)
244 return b
247 #Call by picle for dataify the coment
248 #because we DO NOT WANT REF in this pickleisation!
249 def __getstate__(self):
250 cls = self.__class__
251 # id is not in *_properties
252 res = {'id' : self.id}
253 for prop in cls.properties:
254 if hasattr(self, prop):
255 res[prop] = getattr(self, prop)
257 return res
260 # Inversed funtion of getstate
261 def __setstate__(self, state):
262 cls = self.__class__
263 self.id = state['id']
264 for prop in cls.properties:
265 if prop in state:
266 setattr(self, prop, state[prop])