def init_HTTP(self): """ things to do if HTTP is not initialized """ GenericServer.init_HTTP(self) try: self.sensu_api = SensuAPI(self.api_url, username=self.username, password=self.password) except SensuAPIException: self.Error(sys.exc_info())
def init_HTTP(self): """ things to do if HTTP is not initialized """ GenericServer.init_HTTP(self) if self.custom_cert_use: verify = self.custom_cert_ca_file else: verify = not self.ignore_cert try: self.sensu_api = SensuAPI(self.api_url, username=self.username, password=self.password, verify=verify) except SensuAPIException: self.Error(sys.exc_info())
class SensuServer(GenericServer): TYPE = 'Sensu' SEVERITY_CODE_TEXT_MAP = dict() SEVERITY_STATUS_TEXT_MAP = CaseInsensitiveDict() MENU_ACTIONS = [ 'Monitor', 'Recheck', 'Acknowledge', 'Submit check result', 'Downtime' ] sensu_api = None authentication = 'basic' api_url = '' uchiwa_url = '' uchiwa_datacenter = '' username = '' password = '' def __init__(self, **kwds): GenericServer.__init__(self, **kwds) # Prepare all urls needed by nagstamon self.urls = {} self.statemap = {} self.api_url = conf.servers[self.get_name()].monitor_cgi_url self.uchiwa_url = conf.servers[self.get_name()].monitor_url self.uchiwa_datacenter = conf.servers[self.get_name()].monitor_site self.username = conf.servers[self.get_name()].username self.password = conf.servers[self.get_name()].password self.BROWSER_URLS = { 'monitor': '$MONITOR$', 'hosts': '$MONITOR$/#/clients', 'services': '$MONITOR$/#/checks', 'history': '$MONITOR$/#/clients' } self.SEVERITY_CODE_TEXT_MAP = { 0: 'OK', 1: 'WARNING', 2: 'CRITICAL', 3: 'UNKNOWN' } # SEVERITY_STATUS_TEXT_MAP is a Case-Insensitive dict self.SEVERITY_STATUS_TEXT_MAP['OK'] = 0 self.SEVERITY_STATUS_TEXT_MAP['WARNING'] = 1 self.SEVERITY_STATUS_TEXT_MAP['CRITICAL'] = 2 self.SEVERITY_STATUS_TEXT_MAP['UNKNOWN'] = 3 def init_HTTP(self): """ things to do if HTTP is not initialized """ GenericServer.init_HTTP(self) try: self.sensu_api = SensuAPI(self.api_url, username=self.username, password=self.password) except SensuAPIException: self.Error(sys.exc_info()) def _insert_service_to_hosts(self, service: GenericService): service_host = service.get_host_name() if service_host not in self.new_hosts: self.new_hosts[service_host] = GenericHost() self.new_hosts[service_host].name = service_host self.new_hosts[service_host].site = service.site self.new_hosts[service_host].services[service.name] = service @staticmethod def _aslocaltimestr(utc_dt): local_dt = utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None) return local_dt.strftime('%Y-%m-%d %H:%M:%S') def _get_status(self): self.new_hosts = dict() try: events = self._get_all_events() for event in events: event_check = event['check'] event_client = event['client'] new_service = GenericService() new_service.event_id = event['id'] new_service.host = event_client['name'] new_service.name = event_check['name'] # Uchiwa needs the 'dc' for re_check; Sensu does not if 'dc' in event: new_service.site = event['dc'] else: new_service.site = None new_service.status = None try: new_service.status = self.SEVERITY_CODE_TEXT_MAP.get( event_check['status']) except KeyError: new_service.status = 'UNKNOWN' last_check_time = datetime.utcfromtimestamp( int(event['timestamp'])) new_service.last_check = self._aslocaltimestr(last_check_time) new_service.duration = HumanReadableDurationFromTimestamp( int(event['last_state_change'])) new_service.status_information = event_check['output'] # needs a / with a number on either side to work new_service.attempt = str(event['occurrences']) + '/1' new_service.passiveonly = False new_service.notifications_disabled = event['silenced'] new_service.flapping = False new_service.acknowledged = event['silenced'] new_service.scheduled_downtime = False self._insert_service_to_hosts(new_service) except: self.isChecking = False result, error = self.Error(sys.exc_info()) print(traceback.format_exc()) return Result(result=result, error=error) return Result(error="") def get_username(self): return str(self.username) def get_password(self): return str(self.password) def set_acknowledge(self, info_dict): subscription = self._format_client_subscription(info_dict['host']) try: silenece_args = { 'check': info_dict['service'], 'subscription': subscription, 'reason': info_dict['comment'], 'creator': info_dict['author'], 'expire_on_resolve': True } self.sensu_api.post_silence_request(silenece_args) except SensuAPIException as e: pass @staticmethod def _format_client_subscription(client: str): return 'client:' + client def _acknowledge_client_check(self, client: str, check: str, comment: str = None, author: str = None): subscription = self._format_client_subscription(client) try: silenece_args = { 'check': check, 'subscription': subscription, 'reason': comment, 'creator': author, 'expire_on_resolve': True } self.sensu_api.post_silence_request(silenece_args) except SensuAPIException as e: pass def _get_all_events(self): events = self.sensu_api.get_events() return events def _get_event_duration_string(self, start_seconds: int, end_seconds: int): sec = end_seconds - start_seconds days, rem = divmod(sec, 60 * 60 * 24) hours, rem = divmod(rem, 60 * 60) mins, sec = divmod(rem, 60) if days == 0 and hours == 0 and mins == 0 and sec == 0: return None return '%sd %sh %sm %ss' % (days, hours, mins, sec) def set_recheck(self, info_dict): self.sensu_api.post_check_request( info_dict['service'], self._format_client_subscription(info_dict['host']), self.hosts[info_dict['host']].site) def set_downtime(self, info_dict): subscription = self._format_client_subscription(info_dict['host']) silence_args = { 'check': info_dict['service'], 'subscription': subscription, 'reason': info_dict['comment'], 'creator': info_dict['author'], 'expire': int(info_dict['hours']) * 3600 + int(info_dict['minutes']) * 60, 'expire_on_resolve': False } self.sensu_api.post_silence_request(silence_args) def set_submit_check_result(self, info_dict): sensu_status = None try: sensu_status = self.SEVERITY_STATUS_TEXT_MAP[info_dict['state']] except KeyError: sensu_status = 3 # 3 stands for UNKNOWN, anything other than 0,1,2 is UNKNOWN to Sensu self.sensu_api.post_result_data(info_dict['host'], info_dict['service'], info_dict['check_output'], sensu_status) def get_start_end(self, host): return 'Not Supported!', 'Not Supported!' def open_monitor(self, host, service=''): ''' open monitor from tablewidget context menu ''' detail_url = self.monitor_url + '/#/client/' + self.uchiwa_datacenter + '/' + host if service != '': detail_url += '?check=' + service webbrowser_open(detail_url)