1# encoding: utf-8 2 3# Nagstamon - Nagios status monitor for your desktop 4# Copyright (C) 2008-2021 Henri Wahl <henri@nagstamon.de> et al. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 19 20import urllib.request 21import urllib.parse 22import urllib.error 23import socket 24import sys 25import re 26import copy 27 28from datetime import datetime, timedelta 29 30from Nagstamon.Objects import * 31from Nagstamon.Servers.Generic import GenericServer 32from Nagstamon.Config import conf 33from Nagstamon.Helpers import webbrowser_open 34 35 36class CentreonServer(GenericServer): 37 TYPE = 'Centreon' 38 39 # centreon generic web interface uses a sid which is needed to ask for news 40 SID = None 41 42 # HARD/SOFT state mapping 43 HARD_SOFT = {'(H)': 'hard', '(S)': 'soft'} 44 45 # apparently necessesary because of non-english states as in https://github.com/HenriWahl/Nagstamon/issues/91 (Centeron 2.5) 46 TRANSLATIONS = {'INDISPONIBLE': 'DOWN', 47 'INJOIGNABLE': 'UNREACHABLE', 48 'CRITIQUE': 'CRITICAL', 49 'INCONNU': 'UNKNOWN', 50 'ALERTE': 'WARNING'} 51 52 # Entries for monitor default actions in context menu 53 MENU_ACTIONS = ['Monitor', 'Recheck', 'Acknowledge', 'Downtime'] 54 55 # Centreon works better or at all with html.parser for BeautifulSoup 56 PARSER = 'html.parser' 57 58 # Needed to detect each Centreon's version 59 centreon_version = None 60 # Token that centreon use to protect the system 61 centreon_token = None 62 # To only detect broker once 63 first_login = True 64 # limit number of services retrived 65 limit_services_number = 9999 66 # default value, applies to version 2.2 and others 67 XML_PATH = 'xml' 68 69 def init_config(self): 70 ''' 71 dummy init_config, called at thread start, not really needed here, just omit extra properties 72 ''' 73 # set URLs here already 74 self.init_HTTP() 75 if not self.tls_error and self.centreon_version is not None: 76 self._define_url() 77 78 def init_HTTP(self): 79 """ 80 initialize HTTP connection 81 """ 82 if self.session is None: 83 GenericServer.init_HTTP(self) 84 85 if self.centreon_version is None: 86 result_versioncheck = self.FetchURL(self.monitor_cgi_url + '/index.php', giveback='raw') 87 raw_versioncheck, error_versioncheck = result_versioncheck.result, result_versioncheck.error 88 if error_versioncheck == '': 89 if re.search('2\.2\.[0-9]', raw_versioncheck): 90 self.centreon_version = 2.2 91 if conf.debug_mode is True: 92 self.Debug(server=self.get_name(), debug='Centreon version detected : 2.2') 93 # URLs for browser shortlinks/buttons on popup window 94 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?p=1', 95 'hosts': '$MONITOR$/main.php?p=20103&o=hpb', 96 'services': '$MONITOR$/main.php?p=20202&o=svcpb', 97 'history': '$MONITOR$/main.php?p=203'} 98 elif re.search('2\.[3-6]\.[0-5]', raw_versioncheck): 99 self.centreon_version = 2.3456 100 if conf.debug_mode is True: 101 self.Debug(server=self.get_name(), debug='Centreon version detected : 2.3 <=> 2.6.5') 102 # URLs for browser shortlinks/buttons on popup window 103 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?p=1', 104 'hosts': '$MONITOR$/main.php?p=20103&o=hpb', 105 'services': '$MONITOR$/main.php?p=20202&o=svcpb', 106 'history': '$MONITOR$/main.php?p=203'} 107 elif re.search('2\.6\.[6-9]', raw_versioncheck): 108 self.centreon_version = 2.66 109 if conf.debug_mode is True: 110 self.Debug(server=self.get_name(), debug='Centreon version detected : 2.6.6') 111 # URLs for browser shortlinks/buttons on popup window 112 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?p=1', 113 'hosts': '$MONITOR$/main.php?p=20103&o=hpb', 114 'services': '$MONITOR$/main.php?p=20202&o=svcpb', 115 'history': '$MONITOR$/main.php?p=203'} 116 elif re.search('2\.7\.[0-9]', raw_versioncheck): 117 # Centreon 2.7 only support C. Broker 118 self.centreon_version = 2.7 119 if conf.debug_mode is True: 120 self.Debug(server=self.get_name(), debug='Centreon version detected : 2.7') 121 # URLs for browser shortlinks/buttons on popup window 122 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?', 123 'hosts': '$MONITOR$/main.php?p=20202&o=hpb', 124 'services': '$MONITOR$/main.php?p=20201&o=svcpb', 125 'history': '$MONITOR$/main.php?p=203'} 126 elif re.search('2\.8\.[0-9]', raw_versioncheck): 127 # Centreon 2.8 only support C. Broker 128 self.centreon_version = 2.8 129 if conf.debug_mode is True: 130 self.Debug(server=self.get_name(), debug='Centreon version detected : 2.8') 131 # URLs for browser shortlinks/buttons on popup window 132 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?', 133 'hosts': '$MONITOR$/main.php?p=20202', 134 'services': '$MONITOR$/main.php?p=20201', 135 'history': '$MONITOR$/main.php?p=203'} 136 elif re.search('18\.10\.[0-9]', raw_versioncheck): 137 self.centreon_version = 18.10 138 if conf.debug_mode is True: 139 self.Debug(server=self.get_name(), debug='Centreon version detected : 18.10') 140 # URLs for browser shortlinks/buttons on popup window 141 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?', 142 'hosts': '$MONITOR$/main.php?p=20202', 143 'services': '$MONITOR$/main.php?p=20201', 144 'history': '$MONITOR$/main.php?p=203'} 145 elif re.search('19\.(04|10)\.[0-9]', raw_versioncheck) or re.search('20\.(04|10)\.[0-9]', raw_versioncheck): 146 self.centreon_version = 19.04 147 if conf.debug_mode is True: 148 self.Debug(server=self.get_name(), debug='Centreon version detected : 19.04 <=> 20.10') 149 # URLs for browser shortlinks/buttons on popup window 150 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?', 151 'hosts': '$MONITOR$/main.php?p=20202', 152 'services': '$MONITOR$/main.php?p=20201', 153 'history': '$MONITOR$/main.php?p=203'} 154 else: 155 # unsupported version or unable do determine 156 self.centreon_version = 19.04 157 if conf.debug_mode is True: 158 self.Debug(server=self.get_name(), debug='Centreon version unknown : supposed to be >= 19.04') 159 # URLs for browser shortlinks/buttons on popup window 160 self.BROWSER_URLS = {'monitor': '$MONITOR$/main.php?', 161 'hosts': '$MONITOR$/main.php?p=20202&o=hpb', 162 'services': '$MONITOR$/main.php?p=20201&o=svcpb', 163 'history': '$MONITOR$/main.php?p=203'} 164 else: 165 if conf.debug_mode is True: 166 self.Debug(server=self.get_name(), debug='Error getting the home page : ' + error_versioncheck) 167 168 if self.first_login: 169 self.SID = self._get_sid().result 170 self.first_login = False 171 172 del result_versioncheck, raw_versioncheck, error_versioncheck 173 174 def reset_HTTP(self): 175 ''' 176 Centreon needs deletion of SID 177 ''' 178 self.SID = None 179 self.SID = self._get_sid().result 180 181 def open_monitor(self, host, service=''): 182 if self.use_autologin is True: 183 auth = '&autologin=1&useralias=' + self.username + '&token=' + self.autologin_key 184 else: 185 auth = '' 186 187 # Meta 188 if host == '_Module_Meta': 189 # Centreon < 2.7 190 if self.centreon_version < 2.7: 191 webbrowser_open(self.urls_centreon['index'] + '?' + urllib.parse.urlencode({'p': 20206, 'o': 'meta'}) + auth ) 192 # Centreon 2.7 193 elif self.centreon_version == 2.7: 194 webbrowser_open(self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p':20206, 'o':'meta'}) + auth ) 195 # Centreon 2.8 196 elif self.centreon_version == 2.8: 197 m = re.search(r'^.+ \((?P<rsd>.+)\)$', service) 198 if m: 199 service = m.group('rsd') 200 webbrowser_open(self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p':20201,'o':'svcd','host_name':'_Module_Meta','service_description':service}) + auth ) 201 # Starting from Centreon 18.10 202 else: 203 m = re.search(r'^.+ \((?P<rsd>.+)\)$', service) 204 if m: 205 service = m.group('rsd') 206 webbrowser_open(self.urls_centreon['main_with_frames'] + '?' + urllib.parse.urlencode({'p':20201,'o':'svcd','host_name':'_Module_Meta','service_description':service}) + auth ) 207 208 # must be a host if service is empty 209 elif service == '': 210 if self.centreon_version < 2.7: 211 webbrowser_open(self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p':201,'o':'hd', 'host_name':host}) + auth ) 212 elif self.centreon_version in [2.7, 2.8]: 213 webbrowser_open(self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p':20202,'o':'hd', 'host_name':host}) + auth ) 214 else: 215 webbrowser_open(self.urls_centreon['main_with_frames'] + '?' + urllib.parse.urlencode({'p':20202,'o':'hd', 'host_name':host}) + auth ) 216 217 # so it's a service 218 else: 219 if self.centreon_version < 2.7: 220 webbrowser_open(self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p':202, 'o':'svcd', 'host_name':host, 'service_description':service}) + auth ) 221 elif self.centreon_version in [2.7, 2.8]: 222 webbrowser_open(self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p':20201,'o':'svcd', 'host_name':host, 'service_description':service}) + auth ) 223 else: 224 webbrowser_open(self.urls_centreon['main_with_frames'] + '?' + urllib.parse.urlencode({'p':20201,'o':'svcd', 'host_name':host, 'service_description':service}) + auth ) 225 226 227 def _get_sid(self): 228 ''' 229 gets a shiny new SID for XML HTTP requests to Centreon cutting it out via .partition() from raw HTML 230 additionally get php session cookie 231 ''' 232 try: 233 # Aulogin with key, BROWSER_URLS needs the key 234 if self.use_autologin == True: 235 auth = '&autologin=1&useralias=' + self.username + '&token=' + self.autologin_key 236 self.BROWSER_URLS= { 'monitor': self.BROWSER_URLS['monitor'] + auth,\ 237 'hosts': self.BROWSER_URLS['hosts'] + auth,\ 238 'services': self.BROWSER_URLS['services'] + auth,\ 239 'history': self.BROWSER_URLS['history'] + auth} 240 raw = self.FetchURL(self.monitor_cgi_url + '/index.php?p=101&autologin=1&useralias=' + self.username + '&token=' + self.autologin_key, giveback='raw') 241 if conf.debug_mode == True: 242 self.Debug(server=self.get_name(), debug='Autologin : ' + self.username + ' : ' + self.autologin_key) 243 # Gathering of the token who will be used to interact with Centreon (start with 2.66) 244 if self.centreon_version >= 2.66 and self.centreon_version < 19.04: 245 page = self.FetchURL(self.monitor_cgi_url + '/main.get.php') 246 self.centreon_token = page.result.find('input', {'name': "centreon_token"})['value'] 247 248 # Password auth 249 else: 250 login = self.FetchURL(self.monitor_cgi_url + '/index.php') 251 if login.error == '' and login.status_code == 200: 252 # Centreon >= 2.6.6 implement a token 253 if self.centreon_version >= 2.66 and self.centreon_version <= 19.04: 254 form = login.result.find('form') 255 form_inputs = {} 256 # Need to catch the centreon_token for login to work 257 for form_input in ('centreon_token', 'submitLogin'): 258 form_inputs[form_input] = form.find('input', {'name': form_input})['value'] 259 self.centreon_token = form_inputs['centreon_token'] 260 form_inputs['useralias'] = self.username 261 form_inputs['password'] = self.password 262 # fire up login button with all needed data 263 raw = self.FetchURL(self.monitor_cgi_url + '/index.php', cgi_data=form_inputs) 264 else: 265 login_data = {"useralias" : self.username, "password" : self.password, "submit" : "Login"} 266 raw = self.FetchURL(self.monitor_cgi_url + "/index.php",cgi_data=login_data, giveback="raw") 267 if conf.debug_mode == True: 268 self.Debug(server=self.get_name(), debug='Password login : ' + self.username + ' : ' + self.password) 269 270 sid = self.session.cookies['PHPSESSID'] 271 if conf.debug_mode == True: 272 self.Debug(server=self.get_name(), debug='SID : ' + sid) 273 if self.centreon_version >= 2.66 and self.centreon_version < 19.04: 274 self.Debug(server=self.get_name(), debug='Centreon Token : ' + self.centreon_token) 275 # those broker urls would not be changing too often so this check migth be done here 276 if self.first_login: 277 self._get_xml_path(sid) 278 self.first_login = False 279 return Result(result=sid) 280 281 except: 282 import traceback 283 traceback.print_exc(file=sys.stdout) 284 result, error = self.Error(sys.exc_info()) 285 return Result(result=result, error=error) 286 287 288 def get_start_end(self, host): 289 ''' 290 get start and end time for downtime from Centreon server 291 ''' 292 try: 293 # It's not possible since 18.10 to get date from the webinterface 294 # because it's set in javascript 295 if self.centreon_version < 18.10: 296 cgi_data = {'o':'ah',\ 297 'host_name':host} 298 if self.centreon_version < 2.7: 299 cgi_data['p'] = '20106' 300 elif self.centreon_version == 2.7: 301 cgi_data['p'] = '210' 302 elif self.centreon_version == 2.8: 303 cgi_data['o'] = 'a' 304 cgi_data['p'] = '210' 305 result = self.FetchURL(self.urls_centreon['main'], cgi_data = cgi_data, giveback='obj') 306 307 html, error = result.result, result.error 308 if error == '': 309 start_date = html.find(attrs={'name':'start'}).attrs['value'] 310 start_hour = html.find(attrs={'name':'start_time'}).attrs['value'] 311 start_time = start_date + ' ' + start_hour 312 313 end_date = html.find(attrs={'name':'end'}).attrs['value'] 314 end_hour = html.find(attrs={'name':'end_time'}).attrs['value'] 315 end_time = end_date + ' ' + end_hour 316 return start_time, end_time 317 318 else: 319 start_time = datetime.now().strftime("%m/%d/%Y %H:%M") 320 end_time = datetime.now() + timedelta(hours=2) 321 end_time = end_time.strftime("%m/%d/%Y %H:%M") 322 return start_time, end_time 323 324 except: 325 self.Error(sys.exc_info()) 326 return 'n/a', 'n/a' 327 328 329 def GetHost(self, host): 330 ''' 331 Centreonified way to get host ip - attribute 'a' in down hosts xml is of no use for up 332 hosts so we need to get ip anyway from web page 333 ''' 334 # the fastest method is taking hostname as used in monitor 335 if conf.connect_by_host == True or host == '': 336 return Result(result=host) 337 338 # do a web interface search limited to only one result - the hostname 339 cgi_data = {'sid': self.SID, 340 'search': host, 341 'num': 0, 342 'limit': 1, 343 'sort_type':'hostname', 344 'order': 'ASC', 345 'date_time_format_status': 'd/m/Y H:i:s', 346 'o': 'h', 347 'p': 20102, 348 'time': 0} 349 350 centreon_hosts = self.urls_centreon['xml_hosts'] + '?' + urllib.parse.urlencode(cgi_data) 351 352 result = self.FetchURL(centreon_hosts, giveback='xml') 353 xmlobj, error, status_code = result.result, result.error, result.status_code 354 355 # initialize ip string 356 ip = '' 357 358 if len(xmlobj) != 0: 359 ip = str(xmlobj.l.a.text) 360 # when connection by DNS is not configured do it by IP 361 try: 362 if conf.connect_by_dns == True: 363 # try to get DNS name for ip (reverse DNS), if not available use ip 364 try: 365 address = socket.gethostbyaddr(ip)[0] 366 except: 367 if conf.debug_mode == True: 368 self.Debug(server=self.get_name(), debug='Unable to do a reverse DNS lookup on IP: ' + ip) 369 address = ip 370 else: 371 address = ip 372 except: 373 result, error = self.Error(sys.exc_info()) 374 return Result(result=result, error=error) 375 376 else: 377 result, error = self.Error(sys.exc_info()) 378 return Result(error=error) 379 380 del xmlobj 381 382 # print IP in debug mode 383 if conf.debug_mode == True: 384 self.Debug(server=self.get_name(), debug='IP of %s:' % (host) + ' ' + address) 385 386 # give back host or ip 387 return Result(result=address) 388 389 390 def _get_xml_path(self, sid): 391 ''' 392 Find out where this instance of Centreon is publishing the status XMLs 393 Centreon 2.6 + ndo/c.broker - /include/monitoring/status/Hosts/xml/{ndo,broker}/hostXML.php according to configuration 394 Centreon 2.7 + c.broker - /include/monitoring/status/Hosts/xml/hostXML.php 395 Centreon 2.8 + c.broker - /include/monitoring/status/Hosts/xml/hostXML.php 396 regexping HTML for Javascript 397 ''' 398 if self.centreon_version <= 2.66: 399 # 2.6 support NDO and C. Broker, we must check which one is used 400 cgi_data = {'p':201, 'sid':sid} 401 result = self.FetchURL(self.monitor_cgi_url + '/main.php', cgi_data=cgi_data, giveback='raw') 402 raw, error = result.result, result.error 403 if error == '': 404 if re.search('var _addrXML.*xml\/ndo\/host', raw): 405 self.XML_PATH = 'xml/ndo' 406 if conf.debug_mode == True: 407 self.Debug(server=self.get_name(), debug='Detected broker : NDO') 408 elif re.search('var _addrXML.*xml\/broker\/host', raw): 409 self.XML_PATH = 'xml/broker' 410 if conf.debug_mode == True: 411 self.Debug(server=self.get_name(), debug='Detected broker : C. Broker') 412 else: 413 if conf.debug_mode == True: 414 self.Debug(server=self.get_name(), debug='Could not detect the broker for Centeron 2.[3-6]. Using Centreon Broker') 415 self.XML_PATH = 'xml/broker' 416 del raw 417 else: 418 if conf.debug_mode == True: 419 self.Debug(server=self.get_name(), debug='Unable to fetch the main page to detect the broker : ' + error) 420 del result, error 421 else: 422 if conf.debug_mode == True: 423 self.Debug(server=self.get_name(), debug='Only Centreon Broker is supported in Centeon >= 2.7 -> XML_PATH='+ self.XML_PATH) 424 425 426 def _define_url(self): 427 urls_centreon_2_2 = { 428 'main': self.monitor_cgi_url + '/main.php', 429 'index': self.monitor_cgi_url + '/index.php', 430 'xml_services': self.monitor_cgi_url + '/include/monitoring/status/Services/' + self.XML_PATH + '/serviceXML.php', 431 'xml_hosts': self.monitor_cgi_url + '/include/monitoring/status/Hosts/' + self.XML_PATH + '/hostXML.php', 432 'xml_meta': self.monitor_cgi_url + '/include/monitoring/status/Meta/' + self.XML_PATH + '/metaServiceXML.php', 433 'xml_hostSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/hostSendCommand.php', 434 'xml_serviceSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/serviceSendCommand.php', 435 'external_cmd_cmdPopup': self.monitor_cgi_url + '/include/monitoring/external_cmd/cmdPopup.php', 436 # no idea if this really exist in centreon < 2.7 437 'autologoutXMLresponse': self.monitor_cgi_url + '/include/common/javascript/autologoutXMLresponse.php' 438 } 439 440 # inconsistant url in Centreon 2.7 441 urls_centreon_2_7 = { 442 'main': self.monitor_cgi_url + '/main.php', 443 'index': self.monitor_cgi_url + '/index.php', 444 'xml_services': self.monitor_cgi_url + '/include/monitoring/status/Services/' + self.XML_PATH + '/serviceXML.php', 445 'xml_hosts': self.monitor_cgi_url + '/include/monitoring/status/Hosts/' + self.XML_PATH + '/broker/hostXML.php', 446 'xml_meta': self.monitor_cgi_url + '/include/monitoring/status/Meta/' + self.XML_PATH + '/broker/metaServiceXML.php', 447 'xml_hostSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/hostSendCommand.php', 448 'xml_serviceSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/serviceSendCommand.php', 449 'external_cmd_cmdPopup': self.monitor_cgi_url + '/include/monitoring/external_cmd/cmdPopup.php', 450 'autologoutXMLresponse': self.monitor_cgi_url + '/include/common/javascript/autologoutXMLresponse.php' 451 } 452 453 urls_centreon_2_8 = { 454 'main': self.monitor_cgi_url + '/main.php', 455 'index': self.monitor_cgi_url + '/index.php', 456 'xml_services': self.monitor_cgi_url + '/include/monitoring/status/Services/' + self.XML_PATH + '/serviceXML.php', 457 'xml_hosts': self.monitor_cgi_url + '/include/monitoring/status/Hosts/' + self.XML_PATH + '/hostXML.php', 458 'xml_hostSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/hostSendCommand.php', 459 'xml_serviceSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/serviceSendCommand.php', 460 'external_cmd_cmdPopup': self.monitor_cgi_url + '/include/monitoring/external_cmd/cmdPopup.php', 461 'autologoutXMLresponse': self.monitor_cgi_url + '/include/core/autologout/autologoutXMLresponse.php' 462 } 463 464 urls_centreon_18_10 = { 465 'main': self.monitor_cgi_url + '/main.get.php', 466 # needed to get the frames around the page when opening the monitoring on a host/service 467 'main_with_frames': self.monitor_cgi_url + '/main.php', 468 'index': self.monitor_cgi_url + '/index.php', 469 'xml_services': self.monitor_cgi_url + '/include/monitoring/status/Services/' + self.XML_PATH + '/serviceXML.php', 470 'xml_hosts': self.monitor_cgi_url + '/include/monitoring/status/Hosts/' + self.XML_PATH + '/hostXML.php', 471 'xml_hostSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/hostSendCommand.php', 472 'xml_serviceSendCommand': self.monitor_cgi_url + '/include/monitoring/objectDetails/xml/serviceSendCommand.php', 473 'external_cmd_cmdPopup': self.monitor_cgi_url + '/include/monitoring/external_cmd/cmdPopup.php', 474 'keepAlive': self.monitor_cgi_url + '/api/internal.php?object=centreon_keepalive&action=keepAlive' 475 } 476 477 if self.centreon_version < 2.7: 478 self.urls_centreon = urls_centreon_2_2 479 elif self.centreon_version == 2.7: 480 self.urls_centreon = urls_centreon_2_7 481 elif self.centreon_version == 2.8: 482 self.urls_centreon = urls_centreon_2_8 483 # 18.10 and beyond 484 elif self.centreon_version >= 18.10: 485 self.urls_centreon = urls_centreon_18_10 486 if conf.debug_mode == True: 487 self.Debug(server=self.get_name(), debug='URLs defined for Centreon %s' % (self.centreon_version)) 488 489 490 def _get_host_id(self, host): 491 ''' 492 get host_id via parsing raw html 493 ''' 494 if self.centreon_version < 2.7: 495 cgi_data = {'p': 20102, 'o': 'hd', 'host_name': host, 'sid': self.SID} 496 else: 497 cgi_data = {'p': 20202, 'o': 'hd', 'host_name': host, 'sid': self.SID} 498 499 url = self.urls_centreon['main'] + '?' + urllib.parse.urlencode(cgi_data) 500 501 result = self.FetchURL(url, giveback='raw') 502 raw, error = result.result, result.error 503 504 if error == '': 505 host_id = raw.partition("var host_id = '")[2].partition("'")[0] 506 del raw 507 else: 508 if conf.debug_mode == True: 509 self.Debug(server=self.get_name(), debug='Host ID could not be retrieved.') 510 511 # some cleanup 512 del result, error 513 514 # only if host_id is an usable integer return it 515 try: 516 if int(host_id): 517 if conf.debug_mode == True: 518 self.Debug(server=self.get_name(), host=host, debug='Host ID is ' + host_id) 519 return host_id 520 else: 521 return '' 522 except: 523 return '' 524 525 526 def _get_host_and_service_id(self, host, service): 527 ''' 528 parse a ton of html to get a host and a service id... 529 ''' 530 cgi_data = {'p':'20201',\ 531 'host_name':host,\ 532 'service_description':service,\ 533 'o':'svcd'} 534 535 # This request must be done in a GET, so just encode the parameters and fetch 536 result = self.FetchURL(self.urls_centreon['main'] + '?' + urllib.parse.urlencode(cgi_data), giveback="raw") 537 raw, error = result.result, result.error 538 539 if error == '': 540 host_id = raw.partition("var host_id = '")[2].partition("'")[0] 541 svc_id = raw.partition("var svc_id = '")[2].partition("'")[0] 542 del raw 543 if conf.debug_mode == True: 544 self.Debug(server=self.get_name(), host=host, service=service, debug='- Get host/svc ID : ' + host_id + '/' + svc_id) 545 else: 546 if conf.debug_mode == True: 547 self.Debug(server=self.get_name(), host=host, service=service, debug='- IDs could not be retrieved.') 548 549 # some cleanup 550 del result, error 551 552 # only if host_id is an usable integer return it 553 try: 554 if int(host_id) and int(svc_id): 555 if conf.debug_mode == True: 556 self.Debug(server=self.get_name(), host=host, service=service, debug='- Host & Service ID are valid (int)') 557 return host_id,svc_id 558 else: 559 return '','' 560 except: 561 return '','' 562 563 564 def _get_status(self): 565 ''' 566 Get status from Centreon Server 567 ''' 568 # Be sure that the session is still active 569 result = self._check_session() 570 if result is not None: 571 if result.result == 'ERROR': 572 if 'urls_centreon' in result.error: 573 result.error = 'Connection error' 574 return result 575 576 # services (unknown, warning or critical?) 577 if self.centreon_version < 2.7: 578 nagcgiurl_services = self.urls_centreon['xml_services'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'svcpb', 'sort_type':'status', 'sid':self.SID}) 579 else: 580 nagcgiurl_services = self.urls_centreon['xml_services'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'svcpb', 'p':20201, 'nc':0, 'criticality':0, 'statusService':'svcpb', 'sSetOrderInMemory':1, 'sid':self.SID}) 581 582 # hosts (up or down or unreachable) 583 # define hosts xml URL, because of inconsistant url 584 if self.centreon_version < 2.7: 585 nagcgiurl_hosts = self.urls_centreon['xml_hosts'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'hpb', 'sort_type':'status', 'sid':self.SID}) 586 elif self.centreon_version >= 2.7 and self.centreon_version < 19.04: 587 nagcgiurl_hosts = self.urls_centreon['xml_hosts'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'hpb', 'p':20202, 'criticality':0, 'statusHost':'hpb', 'sSetOrderInMemory':1, 'sid':self.SID}) 588 else: 589 nagcgiurl_hosts = self.urls_centreon['xml_hosts'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'hpb', 'p':20202, 'criticality':0, 'statusHost':'hpb', 'sSetOrderInMemory':1}) 590 591 # hosts - mostly the down ones 592 # unfortunately the hosts status page has a different structure so 593 # hosts must be analyzed separately 594 try: 595 result = self.FetchURL(nagcgiurl_hosts, giveback='xml') 596 xmlobj, error, status_code = result.result, result.error, result.status_code 597 598 # check if any error occured 599 errors_occured = self.check_for_error(xmlobj, error, status_code) 600 601 # if there are errors return them 602 if errors_occured != False: 603 return(errors_occured) 604 605 # Check if the result is not empty 606 if len(xmlobj) == 0: 607 if conf.debug_mode == True: 608 self.Debug(server=self.get_name(), debug='Empty host XML result') 609 return Result(result=None, error="Empty host XML result") 610 611 # in case there are no children session ID is expired 612 if xmlobj.text.lower() == 'bad session id': 613 del xmlobj 614 if conf.debug_mode == True: 615 self.Debug(server=self.get_name(), debug='Bad session ID, retrieving new one...') 616 617 # try again... 618 self.SID = self._get_sid().result 619 result = self.FetchURL(nagcgiurl_hosts, giveback='xml') 620 xmlobj, error, status_code = result.result, result.error, result.status_code 621 errors_occured = self.check_for_error(xmlobj, error, status_code) 622 # if there are errors return them 623 if errors_occured != False: 624 return(errors_occured) 625 626 # a second time a bad session id should raise an error 627 if xmlobj.text.lower() == 'bad session id': 628 if conf.debug_mode == True: 629 self.Debug(server=self.get_name(), debug='Even after renewing session ID, unable to get the XML') 630 return Result(result='ERROR', 631 error='Bad session ID', 632 status_code=status_code) 633 634 for l in xmlobj.findAll('l'): 635 try: 636 # host objects contain service objects 637 if not l.hn.text in self.new_hosts: 638 self.new_hosts[str(l.hn.text)] = GenericHost() 639 self.new_hosts[str(l.hn.text)].name = str(l.hn.text) 640 self.new_hosts[str(l.hn.text)].server = self.name 641 self.new_hosts[str(l.hn.text)].status = str(l.cs.text) 642 # disgusting workaround for https://github.com/HenriWahl/Nagstamon/issues/91 643 if self.new_hosts[str(l.hn.text)].status in self.TRANSLATIONS: 644 self.new_hosts[str(l.hn.text)].status = self.TRANSLATIONS[self.new_hosts[str(l.hn.text)].status] 645 self.new_hosts[str(l.hn.text)].attempt, self.new_hosts[str(l.hn.text)].status_type = str(l.tr.text).split(' ') 646 self.new_hosts[str(l.hn.text)].status_type = self.HARD_SOFT[self.new_hosts[str(l.hn.text)].status_type] 647 self.new_hosts[str(l.hn.text)].last_check = str(l.lc.text) 648 self.new_hosts[str(l.hn.text)].duration = str(l.lsc.text) 649 self.new_hosts[str(l.hn.text)].status_information= str(l.ou.text) 650 if l.find('cih') != None: 651 self.new_hosts[str(l.hn.text)].criticality = str(l.cih.text) 652 else: 653 self.new_hosts[str(l.hn.text)].criticality = '' 654 self.new_hosts[str(l.hn.text)].acknowledged = bool(int(str(l.ha.text))) 655 self.new_hosts[str(l.hn.text)].scheduled_downtime = bool(int(str(l.hdtm.text))) 656 if l.find('is') != None: 657 self.new_hosts[str(l.hn.text)].flapping = bool(int(str(l.find('is').text))) 658 else: 659 self.new_hosts[str(l.hn.text)].flapping = False 660 self.new_hosts[str(l.hn.text)].notifications_disabled = not bool(int(str(l.ne.text))) 661 self.new_hosts[str(l.hn.text)].passiveonly = not bool(int(str(l.ace.text))) 662 except: 663 import traceback 664 traceback.print_exc(file=sys.stdout) 665 # set checking flag back to False 666 self.isChecking = False 667 result, error = self.Error(sys.exc_info()) 668 return Result(result=result, error=error) 669 670 del xmlobj 671 672 except: 673 import traceback 674 traceback.print_exc(file=sys.stdout) 675 # set checking flag back to False 676 self.isChecking = False 677 result, error = self.Error(sys.exc_info()) 678 return Result(result=result, error=error) 679 680 # services 681 try: 682 result = self.FetchURL(nagcgiurl_services, giveback='xml') 683 xmlobj, error, status_code = result.result, result.error, result.status_code 684 685 # check if any error occured 686 errors_occured = self.check_for_error(xmlobj, error, status_code) 687 # if there are errors return them 688 if errors_occured != False: 689 return(errors_occured) 690 691 # Check if the result is not empty 692 if len(xmlobj) == 0: 693 if conf.debug_mode == True: 694 self.Debug(server=self.get_name(), debug='Empty service XML result') 695 return Result(result=None, error="Empty service XML result") 696 697 # in case there are no children session id is invalid 698 if xmlobj.text.lower() == 'bad session id': 699 # debug 700 if conf.debug_mode == True: 701 self.Debug(server=self.get_name(), debug='Bad session ID, retrieving new one...') 702 # try again... 703 self.SID = self._get_sid().result 704 result = self.FetchURL(nagcgiurl_services, giveback='xml') 705 xmlobj, error, status_code = result.result, result.error, result.status_code 706 errors_occured = self.check_for_error(xmlobj, error, status_code) 707 # if there are errors return them 708 if errors_occured != False: 709 return(errors_occured) 710 711 # a second time a bad session id should raise an error 712 if xmlobj.text.lower() == 'bad session id': 713 return Result(result='ERROR', 714 error='Bad session ID', 715 status_code=status_code) 716 717 # In Centreon 2.8, Meta are merged with regular services 718 if self.centreon_version < 2.8: 719 # define meta-services xml URL 720 if self.centreon_version == 2.7: 721 nagcgiurl_meta_services = self.urls_centreon['xml_meta'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'meta', 'sort_type':'status', 'sid':self.SID}) 722 else: 723 nagcgiurl_meta_services = self.urls_centreon['xml_meta'] + '?' + urllib.parse.urlencode({'num':0, 'limit':self.limit_services_number, 'o':'meta', 'sort_type':'status', 'sid':self.SID}) 724 725 # retrive meta-services xml STATUS 726 result_meta = self.FetchURL(nagcgiurl_meta_services, giveback='xml') 727 xmlobj_meta, error_meta, status_code_meta = result_meta.result, result_meta.error, result_meta.status_code 728 729 # check if any error occured 730 errors_occured = self.check_for_error(xmlobj_meta, error_meta, status_code_meta) 731 732 # if there are errors return them 733 if errors_occured != False: 734 return(errors_occured) 735 736 # a second time a bad session id should raise an error 737 if xmlobj_meta.text.lower() == 'bad session id': 738 if conf.debug_mode == True: 739 self.Debug(server=self.get_name(), debug='Even after renewing session ID, unable to get the XML') 740 741 return Result(result='ERROR', 742 error='Bad session ID', 743 status_code=status_code_meta) 744 745 # INSERT META-services xml at the end of the services xml 746 try: 747 xmlobj.append(xmlobj_meta.reponse) 748 except: 749 import traceback 750 traceback.print_exc(file=sys.stdout) 751 # set checking flag back to False 752 self.isChecking = False 753 result, error = self.Error(sys.exc_info()) 754 return Result(result=result, error=error) 755 # do some cleanup 756 del xmlobj_meta 757 758 for l in xmlobj.findAll('l'): 759 try: 760 # host objects contain service objects 761 ###if not self.new_hosts.has_key(str(l.hn.text)): 762 if not l.hn.text in self.new_hosts: 763 self.new_hosts[str(l.hn.text)] = GenericHost() 764 self.new_hosts[str(l.hn.text)].name = str(l.hn.text) 765 self.new_hosts[str(l.hn.text)].status = 'UP' 766 # if a service does not exist create its object 767 if not l.sd.text in self.new_hosts[str(l.hn.text)].services: 768 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)] = GenericService() 769 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].host = str(l.hn.text) 770 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].name = str(l.sd.text) 771 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].server = self.name 772 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status = str(l.cs.text) 773 774 if self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].host == '_Module_Meta': 775 # ajusting service name for Meta services 776 if self.centreon_version < 2.8: 777 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].name = '{} ({})'.format(str(l.sd.text), l.rsd.text) 778 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].attempt = str(l.ca.text) 779 else: 780 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].name = '{} ({})'.format(str(l.sdn.text), l.sdl.text) 781 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].attempt, \ 782 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status_type = str(l.ca.text).split(' ') 783 else: 784 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].attempt, \ 785 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status_type = str(l.ca.text).split(' ') 786 787 # disgusting workaround for https://github.com/HenriWahl/Nagstamon/issues/91 788 # Still needed in Centreon 2.8 at least : https://github.com/HenriWahl/Nagstamon/issues/344 789 # Need enhancement, we can do service state matching with this field <sc>service_unknown</sc> 790 #if self.centreon_version < 2.66: 791 if self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status in self.TRANSLATIONS: 792 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status = self.TRANSLATIONS[\ 793 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status] 794 795 if not (self.centreon_version < 2.8 and self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].host == '_Module_Meta'): 796 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status_type =\ 797 self.HARD_SOFT[self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status_type] 798 799 if conf.debug_mode == True: 800 self.Debug(server=self.get_name(), debug='Parsing service XML (Host/Service/Status_type) ' + self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].host + '/' + self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].name + '/' + self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status_type) 801 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].last_check = str(l.lc.text) 802 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].duration = str(l.d.text) 803 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].status_information = str(l.po.text).replace('\n', ' ').strip() 804 805 if l.find('cih') != None: 806 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].criticality = str(l.cih.text) 807 else: 808 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].criticality = '' 809 810 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].acknowledged = bool(int(str(l.pa.text))) 811 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].notifications_disabled = not bool(int(str(l.ne.text))) 812 813 # for features not available in centreon < 2.8 and meta services 814 if not (self.centreon_version < 2.8 and self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].host == '_Module_Meta'): 815 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].scheduled_downtime = bool(int(str(l.dtm.text))) 816 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].flapping = bool(int(str(l.find('is').text))) 817 self.new_hosts[str(l.hn.text)].services[str(l.sd.text)].passiveonly = not bool(int(str(l.ac.text))) 818 819 except: 820 import traceback 821 traceback.print_exc(file=sys.stdout) 822 # set checking flag back to False 823 self.isChecking = False 824 result, error = self.Error(sys.exc_info()) 825 return Result(result=result, error=error) 826 827 # do some cleanup 828 del xmlobj 829 830 except: 831 import traceback 832 traceback.print_exc(file=sys.stdout) 833 # set checking flag back to False 834 self.isChecking = False 835 result, error = self.Error(sys.exc_info()) 836 return Result(result=result, error=error) 837 838 # return True if all worked well 839 return Result() 840 841 842 def _set_acknowledge(self, host, service, author, comment, sticky, notify, persistent, all_services=[]): 843 # decision about host or service - they have different URLs 844 try: 845 if service == '': 846 # host 847 cgi_data = {'cmd': '14', 848 'host_name': host, 849 'author': author, 850 'comment': comment, 851 'submit': 'Add', 852 'notify': int(notify), 853 'persistent': int(persistent), 854 'sticky': int(sticky), 855 'ackhostservice': '0', 856 'en': '1'} 857 if self.centreon_version < 2.7: 858 cgi_data['p'] = '20105' 859 cgi_data['o'] = 'hpb' 860 else: 861 cgi_data['p'] = '20202' 862 cgi_data['o'] = 'hpb' 863 cgi_data['centreon_token'] = self.centreon_token 864 865 # Post 866 raw = self.FetchURL(self.urls_centreon['main'], cgi_data=cgi_data, giveback='raw') 867 del raw 868 869 # if host is acknowledged and all services should be to or if a service is acknowledged 870 # (and all other on this host too) 871 if service != '' or len(all_services) > 0: 872 # service(s) @ host 873 # if all_services is empty only one service has to be checked - the one clicked 874 # otherwise if there all services should be acknowledged 875 if len(all_services) == 0: all_services = [service] 876 877 # acknowledge all services on a host 878 for s in all_services: 879 cgi_data = {'cmd': '15', 880 'host_name': host, 881 'author': author, 882 'comment': comment, 883 'submit': 'Add', 884 'notify': int(notify), 885 'service_description': s, 886 'force_check': '1', 887 'persistent': int(persistent), 888 # following not needed in 18.10, required in wich version ? 889 'persistant': int(persistent), 890 'sticky': int(sticky), 891 'o': 'svcd', 892 'en': '1'} 893 if self.centreon_version < 2.7: 894 cgi_data['p'] = '20215' 895 else: 896 cgi_data['p'] = '20201' 897 cgi_data['centreon_token'] = self.centreon_token 898 899 # in case of a meta-service, extract the 'rsd' field from the service name : 900 if host == '_Module_Meta': 901 m = re.search(r'^.+ \((?P<rsd>.+)\)$', s) 902 if m: 903 rsd = m.group('rsd') 904 if self.centreon_version < 2.8: 905 cgi_data = {'p': '20206', 906 'o': 'meta', 907 'cmd': '70', 908 'select[' + host + ';' + rsd + ']': '1', 909 'limit': '0'} 910 elif self.centreon_version in [2.8, 18.10]: 911 cgi_data['service_description'] = rsd 912 913 # POST, for some strange reason only working if giveback is 'raw' 914 raw = self.FetchURL(self.urls_centreon['main'], cgi_data=cgi_data, giveback='raw') 915 del raw 916 except: 917 self.Error(sys.exc_info()) 918 919 920 def _set_recheck(self, host, service): 921 ''' 922 host and service ids are needed to tell Centreon what whe want 923 ''' 924 try: 925 # decision about host or service - they have different URLs 926 # Meta 927 if host == '_Module_Meta': 928 if conf.debug_mode == True: 929 self.Debug(server=self.get_name(), debug='Recheck on a Meta service, more work to be done') 930 m = re.search(r'^.+ \((?P<rsd>.+)\)$', service) 931 if m: 932 rsd = m.group('rsd') 933 if self.centreon_version < 2.8: 934 url = self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p': '20206','o': 'meta','cmd': '3','select[' + host + ';' + rsd + ']': '1','limit':'0'}) 935 else: 936 url = self.urls_centreon['main'] + '?' + urllib.parse.urlencode({'p': '202','o': 'svc','cmd': '3','select[' + host + ';' + rsd + ']': '1','limit':'1','centreon_token':self.centreon_token}) 937 938 elif service == '': 939 # ... it can only be a host, so check all his services and there is a command for that 940 host_id = self._get_host_id(host) 941 942 if self.centreon_version < 2.7: 943 url = self.urls_centreon['xml_hostSendCommand'] + '?' + urllib.parse.urlencode({'cmd':'host_schedule_check', 'actiontype':1,'host_id':host_id,'sid':self.SID}) 944 else: 945 url = self.urls_centreon['xml_hostSendCommand'] + '?' + urllib.parse.urlencode({'cmd':'host_schedule_check', 'actiontype':1,'host_id':host_id}) 946 del host_id 947 948 else: 949 # service @ host 950 host_id, service_id = self._get_host_and_service_id(host, service) 951 952 # Starting from 19.04 this must be in POST 953 if self.centreon_version < 19.04: 954 # fill and encode URL data 955 cgi_data = urllib.parse.urlencode({'cmd':'service_schedule_check', 'actiontype':1,\ 956 'host_id':host_id, 'service_id':service_id, 'sid':self.SID}) 957 958 url = self.urls_centreon['xml_serviceSendCommand'] + '?' + cgi_data 959 del host_id, service_id 960 else: 961 cgi_data = {'cmd': 'service_schedule_check', 962 'host_id': host_id, 963 'service_id': service_id, 964 'actiontype': '0'} 965 del host_id, service_id 966 967 if self.centreon_version < 19.04: 968 # execute GET request 969 raw = self.FetchURL(url, giveback='raw') 970 del raw 971 else: 972 # running remote cgi command with POST method, for some strange reason only working if 973 # giveback is 'raw' 974 raw = self.FetchURL(self.urls_centreon['xml_serviceSendCommand'], cgi_data=cgi_data, giveback='raw') 975 del raw 976 except: 977 self.Error(sys.exc_info()) 978 979 980 def _set_downtime(self, host, service, author, comment, fixed, start_time, end_time, hours, minutes): 981 ''' 982 gets actual host and service ids and apply them to downtime cgi 983 ''' 984 try: 985 # duration unit is minute 986 duration = (hours * 60) + minutes 987 # need cmdPopup.php needs boolean 988 if fixed == 1: 989 fixed = 'true' 990 else: 991 fixed = 'false' 992 993 # Host downtime 994 if service == '': 995 if self.centreon_version < 19.04: 996 cgi_data = {'cmd':75,\ 997 'duration':duration,\ 998 'duration_scale':'m',\ 999 'start':start_time,\ 1000 'end':end_time,\ 1001 'comment':comment,\ 1002 'fixed':fixed,\ 1003 'downtimehostservice':'true',\ 1004 'author':author,\ 1005 'sid':self.SID,\ 1006 'select['+host+']':1 1007 } 1008 # Params has changed starting from 19.04 1009 else: 1010 cgi_data = {'cmd':75, 1011 'duration':duration, 1012 'duration_scale':'m', 1013 'comment':comment, 1014 'start':start_time, 1015 'end':end_time, 1016 'host_or_centreon_time':0, 1017 'fixed':fixed, 1018 'downtimehostservice':'true', 1019 'author':author, 1020 'resources':'["'+host+'"]' 1021 } 1022 1023 # Service downtime 1024 else: 1025 # Centreon 2.8 only, in case of a meta-service, extract the 'rsd' field from the service name : 1026 if host == '_Module_Meta' and self.centreon_version in [2.8, 18.10]: 1027 m = re.search(r'^.+ \((?P<rsd>.+)\)$', service) 1028 if m: 1029 rsd = m.group('rsd') 1030 service = rsd 1031 if self.centreon_version < 19.04: 1032 cgi_data = {'cmd':74,\ 1033 'duration':duration,\ 1034 'duration_scale':'m',\ 1035 'start':start_time,\ 1036 'end':end_time,\ 1037 'comment':comment,\ 1038 'fixed':fixed,\ 1039 'downtimehostservice':0,\ 1040 'author':author,\ 1041 'sid':self.SID,\ 1042 'select['+host+';'+service+']':1 1043 } 1044 1045 # Params has changed starting from 19.04 1046 else: 1047 cgi_data = {'cmd':74, 1048 'duration':duration, 1049 'duration_scale':'m', 1050 'comment':comment, 1051 'start':start_time, 1052 'end':end_time, 1053 'host_or_centreon_time':0, 1054 'fixed':fixed, 1055 'downtimehostservice':0, 1056 'author':author, 1057 'resources':'["'+host+'%3B'+service+'"]' 1058 } 1059 1060 if self.centreon_version < 19.04: 1061 # This request must be done in a GET, so just encode the parameters and fetch 1062 raw = self.FetchURL(self.urls_centreon['external_cmd_cmdPopup'] + '?' + urllib.parse.urlencode(cgi_data), giveback="raw") 1063 del raw 1064 # Starting from 19.04, must be POST 1065 else: 1066 # Do it in POST 1067 raw = self.FetchURL(self.urls_centreon['external_cmd_cmdPopup'], cgi_data=cgi_data, giveback='raw') 1068 del raw 1069 1070 except: 1071 self.Error(sys.exc_info()) 1072 1073 1074 def _check_session(self): 1075 if conf.debug_mode == True: 1076 self.Debug(server=self.get_name(), debug='Checking session status') 1077 if 'url_centreon' not in self.__dict__: 1078 self.init_config() 1079 try: 1080 if self.centreon_version >= 18.10: 1081 result = self.FetchURL(self.urls_centreon['keepAlive'], giveback='raw') 1082 self.raw, self.error, self.status_code = result.result, result.error, result.status_code 1083 # Return 200 & null a session is open 1084 if conf.debug_mode == True: 1085 self.Debug(server=self.get_name(), debug='Session status : ' + self.raw + ', http code : ' + str(self.status_code)) 1086 # 401 if no valid session is present 1087 if self.status_code == 401: 1088 self.SID = self._get_sid().result 1089 if conf.debug_mode == True: 1090 self.Debug(server=self.get_name(), debug='Session renewed') 1091 1092 else: 1093 result = self.FetchURL(self.urls_centreon['autologoutXMLresponse'], giveback='xml') 1094 xmlobj, error, status_code = result.result, result.error, result.status_code 1095 self.session_state = xmlobj.find("state").text.lower() 1096 if conf.debug_mode == True: 1097 self.Debug(server=self.get_name(), debug='Session status : ' + self.session_state) 1098 if self.session_state == "nok": 1099 self.SID = self._get_sid().result 1100 if conf.debug_mode == True: 1101 self.Debug(server=self.get_name(), debug='Session renewed') 1102 1103 except: 1104 import traceback 1105 traceback.print_exc(file=sys.stdout) 1106 result, error = self.Error(sys.exc_info()) 1107 return Result(result=result, error=error) 1108