*Fix a bug which prevents eventhandlers and notifications to run as early as possible...
[shinken.git] / shinken / notification.py
blobbfe7cc6ce2265a71ca553a5ef638fa84c7b2fbf6
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 self.creation_time = time.time()
157 #return a copy of the check but just what is important for execution
158 #So we remove the ref and all
159 def copy_shell(self):
160 #We create a dummy check with nothing in it, jsut defaults values
161 return self.copy_shell__( Notification('', '', '', '', '', '', '', id=self.id) )
164 def is_launchable(self, t):
165 return t >= self.t_to_go
168 def is_administrative(self):
169 if self.type in ('PROBLEM', 'RECOVERY'):
170 return False
171 else:
172 return True
175 def __str__(self):
176 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)))
177 #return ''#str(self.__dict__)
180 def get_id(self):
181 return self.id
184 def get_return_from(self, n):
185 self.exit_status = n.exit_status
186 #self.output = c.output
187 #self.check_time = c.check_time
188 #self.execution_time = c.execution_time
191 #Fill data with info of item by looking at brok_type
192 #in props of properties or running_propterties
193 def fill_data_brok_from(self, data, brok_type):
194 cls = self.__class__
195 #Now config properties
196 for prop in cls.properties:
197 if hasattr(prop, 'fill_brok'):
198 if brok_type in cls.properties[prop]['fill_brok']:
199 data[prop] = getattr(self, prop)
202 #Get a brok with initial status
203 def get_initial_status_brok(self):
204 data = {'id' : self.id}
206 self.fill_data_brok_from(data, 'full_status')
207 b = Brok('notification_raise', data)
208 return b
211 #Call by picle for dataify the coment
212 #because we DO NOT WANT REF in this pickleisation!
213 def __getstate__(self):
214 cls = self.__class__
215 # id is not in *_properties
216 res = {'id' : self.id}
217 for prop in cls.properties:
218 if hasattr(self, prop):
219 res[prop] = getattr(self, prop)
221 return res
224 # Inversed funtion of getstate
225 def __setstate__(self, state):
226 cls = self.__class__
227 self.id = state['id']
228 for prop in cls.properties:
229 if prop in state:
230 setattr(self, prop, state[prop])
231 # Hook for load of 0.4 notification : there were no
232 # creation time, must put one
233 if not hasattr(self, 'creation_time'):
234 self.creation_time = time.time()