Esempio n. 1
0
 def _create_host(self, data):
     """create GenericHost from json data"""
     result = self._update_object(GenericHost(), data)
     result.name = data['custom_variables']['_HOST_NAME']
     result.svid = data['name']
     result.display_name = data['custom_variables']['_HOST_NAME']
     result.alias = data['alias']
     result.address = data['address']
     result.custom_variables = data['custom_variables']
     result.show_name = data['custom_variables']['_HOST_NAME']
     # 2017_06_02
     log.debug('data for obj %s is: %s', result.name, data)
     log.debug("monitos3 host name is %s", result.name)
     log.debug("monitos3 host custom_variables are %s",
               result.custom_variables)
     log.debug("monitos3 host address is %s", result.address)
     # TODO: fix other host states
     host_states = {0: 'UP', 1: 'DOWN', 2: 'UNREACHABLE'}
     # host_states = { 0: 'UP', 1: 'DOWN', 2: 'UNREACHABLE', 3: 'OTHER' }
     host_state_list = [0, 1, 2]
     if data['state'] in host_state_list:
         result.status = host_states[data['state']]
     else:
         result.status = 'OTHER'
     return result
Esempio n. 2
0
    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].services[service.name] = service
Esempio n. 3
0
 def _create_host(self, data):
     """create GenericHost from json data"""
     result = self._update_object(GenericHost(), data)
     result.name = data['name']
     host_states = {0: 'UP', 1: 'DOWN', 2: 'UNKNOWN'}
     result.status = host_states[data['state']]
     return result
Esempio n. 4
0
def executeCli():
    # from Nagstamon.Config import (conf,
    # debug_queue)
    from Nagstamon.Config import conf

    from Nagstamon.Servers import (create_server)

    # Initialize global configuration

    from Nagstamon.Objects import (GenericHost)

    # creates new server object from given servername
    server = create_server(conf.servers[conf.cli_args.servername])

    # gets the current default start/endtime from the server (default current time + 2h)
    start_end_time = server.get_start_end(conf.cli_args.hostname)
    default_start_time = start_end_time[0]
    default_end_time = start_end_time[1]
    # gets the default downtime duration from the nagstamon config
    # default_downtime = conf.defaults_downtime_duration_minutes  # never used

    server.GetStatus()

    server.hosts[conf.cli_args.hostname] = GenericHost()
    server.hosts[conf.cli_args.hostname].name = conf.cli_args.hostname
    server.hosts[conf.cli_args.hostname].server = server.name
    server.hosts[conf.cli_args.hostname].site = "monitor"

    fixedType = {"y": True, "n": False}

    info_dict = dict()
    info_dict['host'] = conf.cli_args.hostname
    info_dict['service'] = conf.cli_args.service
    info_dict['author'] = server.username
    info_dict['comment'] = conf.cli_args.comment
    info_dict['fixed'] = fixedType[conf.cli_args.fixed]

    info_dict['start_time'] = checkDefaultValue(conf.cli_args.start_time,
                                                default_start_time)
    info_dict['end_time'] = default_end_time

    info_dict['hours'] = checkDefaultValue(conf.cli_args.hours, 0)
    info_dict['minutes'] = checkDefaultValue(
        conf.cli_args.minutes, conf.defaults_downtime_duration_minutes)
    info_dict['view_name'] = "host"

    info_dict = createEndTime(info_dict)
    # creates output,v which parameter were processed
    if conf.cli_args.output == 'y':
        print('trying to downtime host "' + info_dict['host'] +
              '", with the following parameters:')
        if info_dict['service'] != "":
            print('service: ', info_dict['service'])
        if info_dict['comment'] is not None:
            print('comment: ', info_dict['comment'])
        print('fixed: ', info_dict['fixed'])
        print('start time: ', info_dict['start_time'])
        print('end time: ', info_dict['end_time'])

    server.set_downtime(info_dict)
Esempio n. 5
0
 def _insert_service_to_hosts(self, service: GenericService):
     """
     We want to create hosts for faulty services as GenericService requires
     that logic.
     """
     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
Esempio n. 6
0
    def _get_status(self):
        """
            Get status from Icinga Server - only JSON
        """
        # define CGI URLs for hosts and services
        if self.cgiurl_hosts == self.cgiurl_services == self.cgiurl_monitoring_health == None:
            # services (unknown, warning or critical?)
            self.cgiurl_services = {'hard': self.monitor_cgi_url + '/monitoring/list/services?service_state>0&service_state<=3&service_state_type=1&addColumns=service_last_check,service_is_reachable&format=json', \
                                    'soft': self.monitor_cgi_url + '/monitoring/list/services?service_state>0&service_state<=3&service_state_type=0&addColumns=service_last_check,service_is_reachable&format=json'}
            # hosts (up or down or unreachable)
            self.cgiurl_hosts = {'hard': self.monitor_cgi_url + '/monitoring/list/hosts?host_state>0&host_state<=2&host_state_type=1&addColumns=host_last_check&format=json', \
                                 'soft': self.monitor_cgi_url + '/monitoring/list/hosts?host_state>0&host_state<=2&host_state_type=0&addColumns=host_last_check&format=json'}
            # monitoring health
            self.cgiurl_monitoring_health = self.monitor_cgi_url + '/monitoring/health/info?format=json'

        # new_hosts dictionary
        self.new_hosts = dict()

        # hosts - mostly the down ones
        # now using JSON output from Icinga
        try:
            for status_type in 'hard', 'soft':
                # first attempt
                result = self.FetchURL(self.cgiurl_hosts[status_type],
                                       giveback='raw')
                # authentication errors get a status code 200 too back because its
                # HTML works fine :-(
                if result.status_code < 400 and\
                   result.result.startswith('<'):
                    # in case of auth error reset HTTP session and try again
                    self.reset_HTTP()
                    result = self.FetchURL(self.cgiurl_hosts[status_type],
                                           giveback='raw')
                    # if it does not work again tell GUI there is a problem
                    if result.status_code < 400 and\
                       result.result.startswith('<'):
                        self.refresh_authentication = True
                        return Result(result=result.result,
                                      error='Authentication error',
                                      status_code=result.status_code)

                # purify JSON result of unnecessary control sequence \n
                jsonraw, error, status_code = copy.deepcopy(result.result.replace('\n', '')),\
                                              copy.deepcopy(result.error),\
                                              result.status_code

                if error != '' or status_code >= 400:
                    return Result(result=jsonraw,
                                  error=error,
                                  status_code=status_code)

                # check if any error occured
                self.check_for_error(jsonraw, error, status_code)

                # Check if the backend is running
                # If it isn't running the last values stored in the database are returned/shown
                # Unfortunately we need to make a extra request for this and only, if monitoring health is possible
                if self.cgiurl_monitoring_health:
                    try:
                        result = self.FetchURL(self.cgiurl_monitoring_health,
                                               giveback='raw')
                        monitoring_health = json.loads(result.result)[0]
                        if (monitoring_health['is_currently_running'] == '0'):
                            return Result(result=monitoring_health,
                                          error='Icinga2 backend not running')
                    except json.decoder.JSONDecodeError:
                        # https://github.com/HenriWahl/Nagstamon/issues/619
                        # Icinga2 monitoring health status query does not seem to work (on older version?)
                        self.cgiurl_monitoring_health = None

                hosts = json.loads(jsonraw)

                for host in hosts:
                    # make dict of tuples for better reading
                    h = dict(host.items())

                    # host
                    if self.use_display_name_host == False:
                        # according to http://sourceforge.net/p/nagstamon/bugs/83/ it might
                        # better be host_name instead of host_display_name
                        # legacy Icinga adjustments
                        if 'host_name' in h: host_name = h['host_name']
                        elif 'host' in h: host_name = h['host']
                    else:
                        # https://github.com/HenriWahl/Nagstamon/issues/46 on the other hand has
                        # problems with that so here we go with extra display_name option
                        host_name = h['host_display_name']

                    # host objects contain service objects
                    if not host_name in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].server = self.name
                        self.new_hosts[host_name].status = self.STATES_MAPPING[
                            'hosts'][int(h['host_state'])]
                        self.new_hosts[
                            host_name].last_check = datetime.datetime.fromtimestamp(
                                int(h['host_last_check']))
                        self.new_hosts[host_name].attempt = h['host_attempt']
                        self.new_hosts[
                            host_name].status_information = BeautifulSoup(
                                h['host_output'].replace('\n', ' ').strip(),
                                'html.parser').text
                        self.new_hosts[host_name].passiveonly = not (int(
                            h['host_active_checks_enabled']))
                        self.new_hosts[
                            host_name].notifications_disabled = not (int(
                                h['host_notifications_enabled']))
                        self.new_hosts[host_name].flapping = bool(
                            int(h['host_is_flapping']))
                        self.new_hosts[host_name].acknowledged = bool(
                            int(h['host_acknowledged']))
                        self.new_hosts[host_name].scheduled_downtime = bool(
                            int(h['host_in_downtime']))
                        self.new_hosts[host_name].status_type = status_type

                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs host_description and no display name
                        self.new_hosts[host_name].real_name = h['host_name']

                        # Icinga only updates the attempts for soft states. When hard state is reached, a flag is set and
                        # attemt is set to 1/x.
                        if (status_type == 'hard'):
                            try:
                                maxAttempts = h['host_attempt'].split('/')[1]
                                self.new_hosts[
                                    host_name].attempt = "{0}/{0}".format(
                                        maxAttempts)
                            except Exception:
                                self.new_hosts[host_name].attempt = "HARD"

                        # extra duration needed for calculation
                        if h['host_last_state_change'] is not None:
                            last_change = h['host_last_state_change'] if h[
                                'host_last_state_change'] is not None else 0
                            duration = datetime.datetime.now(
                            ) - datetime.datetime.fromtimestamp(
                                int(last_change))
                            self.new_hosts[host_name].duration = strfdelta(
                                duration,
                                '{days}d {hours}h {minutes}m {seconds}s')
                        else:
                            self.new_hosts[host_name].duration = 'n/a'
                    del h, host_name
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            for status_type in 'hard', 'soft':
                result = self.FetchURL(self.cgiurl_services[status_type],
                                       giveback='raw')
                # purify JSON result of unnecessary control sequence \n
                jsonraw, error, status_code = copy.deepcopy(result.result.replace('\n', '')),\
                                              copy.deepcopy(result.error),\
                                              result.status_code

                if error != '' or status_code >= 400:
                    return Result(result=jsonraw,
                                  error=error,
                                  status_code=status_code)

                # check if any error occured
                self.check_for_error(jsonraw, error, status_code)

                services = copy.deepcopy(json.loads(jsonraw))

                for service in services:
                    # make dict of tuples for better reading
                    s = dict(service.items())

                    if self.use_display_name_host == False:
                        # according to http://sourceforge.net/p/nagstamon/bugs/83/ it might
                        # better be host_name instead of host_display_name
                        # legacy Icinga adjustments
                        if 'host_name' in s: host_name = s['host_name']
                        elif 'host' in s: host_name = s['host']
                    else:
                        # https://github.com/HenriWahl/Nagstamon/issues/46 on the other hand has
                        # problems with that so here we go with extra display_name option
                        host_name = s['host_display_name']

                    # host objects contain service objects
                    if not host_name in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].status = 'UP'
                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs host_description and no display name
                        self.new_hosts[host_name].real_name = s['host_name']

                    service_name = s['service_display_name']

                    # if a service does not exist create its object
                    if not service_name in self.new_hosts[host_name].services:
                        self.new_hosts[host_name].services[
                            service_name] = GenericService()
                        self.new_hosts[host_name].services[
                            service_name].host = host_name
                        self.new_hosts[host_name].services[
                            service_name].name = service_name
                        self.new_hosts[host_name].services[
                            service_name].server = self.name
                        self.new_hosts[host_name].services[
                            service_name].status = self.STATES_MAPPING[
                                'services'][int(s['service_state'])]
                        self.new_hosts[host_name].services[
                            service_name].last_check = datetime.datetime.fromtimestamp(
                                int(s['service_last_check']))
                        self.new_hosts[host_name].services[
                            service_name].attempt = s['service_attempt']
                        self.new_hosts[host_name].services[
                            service_name].status_information = BeautifulSoup(
                                s['service_output'].replace('\n', ' ').strip(),
                                'html.parser').text
                        self.new_hosts[host_name].services[
                            service_name].passiveonly = not (int(
                                s['service_active_checks_enabled']))
                        self.new_hosts[host_name].services[
                            service_name].notifications_disabled = not (int(
                                s['service_notifications_enabled']))
                        self.new_hosts[host_name].services[
                            service_name].flapping = bool(
                                int(s['service_is_flapping']))
                        self.new_hosts[host_name].services[
                            service_name].acknowledged = bool(
                                int(s['service_acknowledged']))
                        self.new_hosts[host_name].services[
                            service_name].scheduled_downtime = bool(
                                int(s['service_in_downtime']))
                        self.new_hosts[host_name].services[
                            service_name].status_type = status_type
                        self.new_hosts[host_name].services[
                            service_name].unreachable = s[
                                'service_is_reachable'] == '0'

                        if self.new_hosts[host_name].services[
                                service_name].unreachable:
                            self.new_hosts[host_name].services[
                                service_name].status_information += " (SERVICE UNREACHABLE)"

                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs service_description and no display name
                        self.new_hosts[host_name].services[
                            service_name].real_name = s['service_description']

                        # Icinga only updates the attempts for soft states. When hard state is reached, a flag is set and
                        # attemt is set to 1/x.
                        if (status_type == 'hard'):
                            try:
                                maxAttempts = s['service_attempt'].split(
                                    '/')[1]
                                self.new_hosts[host_name].services[
                                    service_name].attempt = "{0}/{0}".format(
                                        maxAttempts)
                            except Exception:
                                self.new_hosts[host_name].services[
                                    service_name].attempt = "HARD"

                        # extra duration needed for calculation
                        if s['service_last_state_change'] is not None:
                            last_change = s['service_last_state_change'] if s[
                                'service_last_state_change'] is not None else 0
                            duration = datetime.datetime.now(
                            ) - datetime.datetime.fromtimestamp(
                                int(last_change))
                            self.new_hosts[host_name].services[
                                service_name].duration = strfdelta(
                                    duration,
                                    '{days}d {hours}h {minutes}m {seconds}s')
                        else:
                            self.new_hosts[host_name].services[
                                service_name].duration = 'n/a'

                    del s, host_name, service_name
        except:

            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # some cleanup
        del jsonraw, error, hosts, services

        # dummy return in case all is OK
        return Result()
Esempio n. 7
0
    def _get_status(self):
        """
        Get status from Nagios Server
        """
        ret = Result()
        # create Nagios items dictionary with to lists for services and hosts
        # every list will contain a dictionary for every failed service/host
        # this dictionary is only temporarily
        nagitems = {"services": [], "hosts": []}

        # Create URLs for the configured filters
        if self.zapi is None:
            self._login()

        try:
            hosts = []
            try:
                hosts = self.zapi.host.get({
                    "output": [
                        "host", "ip", "status", "available", "error",
                        "errors_from"
                    ],
                    "filter": {}
                })
            except:
                # set checking flag back to False
                self.isChecking = False
                result, error = self.Error(sys.exc_info())
                return Result(result=result, error=error)

            for host in hosts:
                n = {
                    'host':
                    host['host'],
                    'status':
                    self.statemap.get(host['available'], host['available']),
                    'last_check':
                    'n/a',
                    'duration':
                    HumanReadableDurationFromTimestamp(host['errors_from']),
                    'status_information':
                    host['error'],
                    'attempt':
                    '1/1',
                    'site':
                    '',
                    'address':
                    host['host'],
                }

                # add dictionary full of information about this host item to nagitems
                nagitems["hosts"].append(n)
                # after collection data in nagitems create objects from its informations
                # host objects contain service objects
                if n["host"] not in self.new_hosts:
                    new_host = n["host"]
                    self.new_hosts[new_host] = GenericHost()
                    self.new_hosts[new_host].name = n["host"]
                    self.new_hosts[new_host].status = n["status"]
                    self.new_hosts[new_host].last_check = n["last_check"]
                    self.new_hosts[new_host].duration = n["duration"]
                    self.new_hosts[new_host].attempt = n["attempt"]
                    self.new_hosts[new_host].status_information = n[
                        "status_information"]
                    self.new_hosts[new_host].site = n["site"]
                    self.new_hosts[new_host].address = n["address"]
        except ZabbixError:
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        services = []
        groupids = []
        zabbix_triggers = []
        try:
            api_version = self.zapi.api_version()
        except ZabbixAPIException:
            # FIXME Is there a cleaner way to handle this? I just borrowed
            # this code from 80 lines ahead. -- AGV
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)

        try:
            response = []
            try:
                #service = self.zapi.trigger.get({"select_items":"extend","monitored":1,"only_true":1,"min_severity":3,"output":"extend","filter":{}})

                triggers_list = []
                if self.monitor_cgi_url:
                    group_list = self.monitor_cgi_url.split(',')

                    #hostgroup_ids = [x['groupid'] for x in self.zapi.hostgroup.get(
                    #    {'output': 'extend',
                    #     'with_monitored_items': True,
                    #     'filter': {"name": group_list}}) if int(x['internal']) == 0]

                    # only without filter there is anything shown at all
                    hostgroup_ids = [
                        x['groupid'] for x in self.zapi.hostgroup.get(
                            {
                                'output': 'extend',
                                'with_monitored_items': True
                            }) if int(x['internal']) == 0
                    ]

                    zabbix_triggers = self.zapi.trigger.get({
                        'sortfield':
                        'lastchange',
                        'withLastEventUnacknowledged':
                        True,
                        'groupids':
                        hostgroup_ids,
                        "monitored":
                        True,
                        "filter": {
                            'value': 1
                        }
                    })
                else:
                    zabbix_triggers = self.zapi.trigger.get({
                        'sortfield':
                        'lastchange',
                        'withLastEventUnacknowledged':
                        True,
                        "monitored":
                        True,
                        "filter": {
                            'value': 1
                        }
                    })
                triggers_list = []

                for trigger in zabbix_triggers:
                    triggers_list.append(trigger.get('triggerid'))
                this_trigger = self.zapi.trigger.get({
                    'triggerids': triggers_list,
                    'expandDescription': True,
                    'output': 'extend',
                    'select_items': 'extend',
                    'expandData': True
                })
                if type(this_trigger) is dict:
                    for triggerid in list(this_trigger.keys()):
                        services.append(this_trigger[triggerid])
                elif type(this_trigger) is list:
                    for trigger in this_trigger:
                        services.append(trigger)

            except ZabbixAPIException:
                # FIXME Is there a cleaner way to handle this? I just borrowed
                # this code from 80 lines ahead. -- AGV
                # set checking flag back to False
                self.isChecking = False
                result, error = self.Error(sys.exc_info())
                print(sys.exc_info())
                return Result(result=result, error=error)

            except ZabbixError as e:
                #print "------------------------------------"
                #print "%s" % e.result.error
                if e.terminate:
                    return e.result
                else:
                    service = e.result.content
                    ret = e.result

            for service in services:
                if api_version > '1.8':
                    state = '%s' % service['description']
                else:
                    state = '%s=%s' % (service['items'][0]['key_'],
                                       service['items'][0]['lastvalue'])
                n = {
                    'host':
                    service['host'],
                    'service':
                    service['description'],
                    'status':
                    self.statemap.get(service['priority'],
                                      service['priority']),
                    # 1/1 attempt looks at least like there has been any attempt
                    'attempt':
                    '1/1',
                    'duration':
                    HumanReadableDurationFromTimestamp(service['lastchange']),
                    'status_information':
                    state,
                    'passiveonly':
                    'no',
                    'last_check':
                    'n/a',
                    'notifications':
                    'yes',
                    'flapping':
                    'no',
                    'site':
                    '',
                    'command':
                    'zabbix',
                    'triggerid':
                    service['triggerid'],
                }

                nagitems["services"].append(n)
                # after collection data in nagitems create objects of its informations
                # host objects contain service objects
                if n["host"] not in self.new_hosts:
                    self.new_hosts[n["host"]] = GenericHost()
                    self.new_hosts[n["host"]].name = n["host"]
                    self.new_hosts[n["host"]].status = "UP"
                    self.new_hosts[n["host"]].site = n["site"]
                    self.new_hosts[n["host"]].address = n["host"]
                    # if a service does not exist create its object
                if n["service"] not in self.new_hosts[n["host"]].services:
                    # workaround for non-existing (or not found) host status flag
                    if n["service"] == "Host is down %s" % (n["host"]):
                        self.new_hosts[n["host"]].status = "DOWN"
                        # also take duration from "service" aka trigger
                        self.new_hosts[n["host"]].duration = n["duration"]
                    else:
                        new_service = n["service"]
                        self.new_hosts[n["host"]].services[
                            new_service] = GenericService()
                        self.new_hosts[
                            n["host"]].services[new_service].host = n["host"]

                        # next dirty workaround to get Zabbix events to look Nagios-esque
                        if (" on " or " is ") in n["service"]:
                            for separator in [" on ", " is "]:
                                n["service"] = n["service"].split(separator)[0]
                        self.new_hosts[n["host"]].services[
                            new_service].name = n["service"]

                        self.new_hosts[n["host"]].services[
                            new_service].status = n["status"]
                        self.new_hosts[n["host"]].services[
                            new_service].last_check = n["last_check"]
                        self.new_hosts[n["host"]].services[
                            new_service].duration = n["duration"]
                        self.new_hosts[n["host"]].services[
                            new_service].attempt = n["attempt"]
                        self.new_hosts[n["host"]].services[
                            new_service].status_information = n[
                                "status_information"]
                        #self.new_hosts[n["host"]].services[new_service].passiveonly = n["passiveonly"]
                        self.new_hosts[n["host"]].services[
                            new_service].passiveonly = False
                        #self.new_hosts[n["host"]].services[new_service].flapping = n["flapping"]
                        self.new_hosts[
                            n["host"]].services[new_service].flapping = False
                        self.new_hosts[
                            n["host"]].services[new_service].site = n["site"]
                        self.new_hosts[n["host"]].services[
                            new_service].address = n["host"]
                        self.new_hosts[n["host"]].services[
                            new_service].command = n["command"]
                        self.new_hosts[n["host"]].services[
                            new_service].triggerid = n["triggerid"]
        except (ZabbixError, ZabbixAPIException):
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)

        return ret
Esempio n. 8
0
    def _get_status(self):
        """
            Get status from Zabbix Server
        """
        ret = Result()
        # create Nagios items dictionary with to lists for services and hosts
        # every list will contain a dictionary for every failed service/host
        # this dictionary is only temporarily
        nagitems = {"services": [], "hosts": []}

        # Create URLs for the configured filters
        if self.zapi is None:
            self._login()

        try:
            hosts = []
            try:
                hosts = self.zapi.host.get({
                    "output": [
                        "host", "ip", "status", "available", "error",
                        "errors_from"
                    ],
                    "filter": {}
                })
            except (ZabbixError, ZabbixAPIException):
                # set checking flag back to False
                self.isChecking = False
                result, error = self.Error(sys.exc_info())
                return Result(result=result, error=error)

            for host in hosts:
                # if host is disabled on server safely ignore it
                if host['available'] != '0':
                    n = {
                        'host':
                        host['host'],
                        'status':
                        self.statemap.get(host['status'], host['status']),
                        'last_check':
                        'n/a',
                        'duration':
                        HumanReadableDurationFromTimestamp(
                            host['errors_from']),
                        'status_information':
                        host['error'],
                        'attempt':
                        '1/1',
                        'site':
                        '',
                        'address':
                        host['host'],
                    }

                    # Zabbix shows OK hosts too - kick 'em!
                    if not n['status'] == 'OK':

                        # add dictionary full of information about this host item to nagitems
                        nagitems["hosts"].append(n)
                        # after collection data in nagitems create objects from its informations
                        # host objects contain service objects
                        if n["host"] not in self.new_hosts:
                            new_host = n["host"]
                            self.new_hosts[new_host] = GenericHost()
                            self.new_hosts[new_host].name = n["host"]
                            self.new_hosts[new_host].status = n["status"]
                            self.new_hosts[new_host].last_check = n[
                                "last_check"]
                            self.new_hosts[new_host].duration = n["duration"]
                            self.new_hosts[new_host].attempt = n["attempt"]
                            self.new_hosts[new_host].status_information = n[
                                "status_information"]
                            self.new_hosts[new_host].site = n["site"]
                            self.new_hosts[new_host].address = n["address"]
        except ZabbixError:
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        services = []
        # groupids = [] # never used - probably old code
        zabbix_triggers = []
        try:
            api_version = self.zapi.api_version()
        except ZabbixAPIException:
            # FIXME Is there a cleaner way to handle this? I just borrowed
            # this code from 80 lines ahead. -- AGV
            # set checking flag back to False

            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)

        try:
            # response = [] # never used - probably old code
            try:
                triggers_list = []

                hostgroup_ids = [
                    x['groupid'] for x in self.zapi.hostgroup.get(
                        {
                            'output': 'extend',
                            'with_monitored_items': True
                        }) if int(x['internal']) == 0
                ]

                zabbix_triggers = self.zapi.trigger.get({
                    'sortfield':
                    'lastchange',
                    'withLastEventUnacknowledged':
                    True,
                    'groupids':
                    hostgroup_ids,
                    "monitored":
                    True,
                    "filter": {
                        'value': 1
                    }
                })

                triggers_list = []

                for trigger in zabbix_triggers:
                    triggers_list.append(trigger.get('triggerid'))
                this_trigger = self.zapi.trigger.get({
                    'triggerids': triggers_list,
                    'expandDescription': True,
                    'output': 'extend',
                    'select_items': 'extend',  # thats for zabbix api 1.8
                    'selectItems': 'extend',  # thats for zabbix api 2.0+
                    'expandData': True
                })
                if type(this_trigger) is dict:
                    for triggerid in list(this_trigger.keys()):
                        services.append(this_trigger[triggerid])
                        this_item = self.zapi.item.get({
                            'itemids':
                            [this_trigger[triggerid]['items'][0]['itemid']],
                            'selectApplications':
                            'extend'
                        })
                        last_app = len(this_item[0]['applications']) - 1
                        this_trigger[triggerid]['application'] = this_item[0][
                            'applications'][last_app]['name']
                elif type(this_trigger) is list:
                    for trigger in this_trigger:
                        services.append(trigger)
                        this_item = self.zapi.item.get({
                            'itemids':
                            trigger['items'][0]['itemid'],
                            'selectApplications':
                            'extend'
                        })
                        # last_app = 0  # use it to get the first application name
                        last_app = len(
                            this_item[0]['applications']
                        ) - 1  # use it to get the last application name
                        trigger['application'] = this_item[0]['applications'][
                            last_app]['name']

            except ZabbixAPIException:
                # FIXME Is there a cleaner way to handle this? I just borrowed
                # this code from 80 lines ahead. -- AGV
                # set checking flag back to False
                self.isChecking = False
                result, error = self.Error(sys.exc_info())
                print(sys.exc_info())
                return Result(result=result, error=error)

            except ZabbixError as e:
                if e.terminate:
                    return e.result
                else:
                    service = e.result.content
                    ret = e.result

            for service in services:
                # Zabbix probably shows OK services too - kick 'em!
                # UPDATE Zabbix api 3.0 doesn't but I didn't tried with older
                #        so I left it
                status = self.statemap.get(service['priority'],
                                           service['priority'])
                if not status == 'OK':
                    if not service['description'].endswith('...'):
                        state = service['description']
                    else:
                        state = service['items'][0]['lastvalue']
                    lastcheck = 0
                    for item in service['items']:
                        if int(item['lastclock']) > lastcheck:
                            lastcheck = int(item['lastclock'])
                    if len(service['comments']) == 0:
                        srvc = service['application']
                    else:
                        srvc = self.nagiosify_service(service['comments'])
                    n = {
                        'service':
                        srvc,
                        'status':
                        status,
                        # 1/1 attempt looks at least like there has been any attempt
                        'attempt':
                        '1/1',
                        'duration':
                        HumanReadableDurationFromTimestamp(
                            service['lastchange']),
                        'status_information':
                        state,
                        'passiveonly':
                        'no',
                        'last_check':
                        time.strftime("%d/%m/%Y %H:%M:%S",
                                      time.localtime(lastcheck)),
                        'notifications':
                        'yes',
                        'flapping':
                        'no',
                        'site':
                        '',
                        'command':
                        'zabbix',
                        'triggerid':
                        service['triggerid'],
                    }

                    if api_version >= '3.0':
                        n['host'] = self.zapi.host.get({
                            "output": ["host"],
                            "filter": {},
                            "triggerids":
                            service['triggerid']
                        })[0]['host']
                    else:
                        n['host'] = service['host']

                    nagitems["services"].append(n)
                    # after collection data in nagitems create objects of its informations
                    # host objects contain service objects
                    if n["host"] not in self.new_hosts:
                        self.new_hosts[n["host"]] = GenericHost()
                        self.new_hosts[n["host"]].name = n["host"]
                        self.new_hosts[n["host"]].status = "UP"
                        self.new_hosts[n["host"]].site = n["site"]
                        self.new_hosts[n["host"]].address = n["host"]
                        # if a service does not exist create its object
                    if n["service"] not in self.new_hosts[n["host"]].services:
                        # workaround for non-existing (or not found) host status flag
                        if n["service"] == "Host is down %s" % (n["host"]):
                            self.new_hosts[n["host"]].status = "DOWN"
                            # also take duration from "service" aka trigger
                            self.new_hosts[n["host"]].duration = n["duration"]
                        else:
                            new_service = n["service"]
                            self.new_hosts[n["host"]].services[
                                new_service] = GenericService()
                            self.new_hosts[n["host"]].services[
                                new_service].host = n["host"]
                            self.new_hosts[n["host"]].services[
                                new_service].name = n["service"]
                            self.new_hosts[n["host"]].services[
                                new_service].status = n["status"]
                            self.new_hosts[n["host"]].services[
                                new_service].last_check = n["last_check"]
                            self.new_hosts[n["host"]].services[
                                new_service].duration = n["duration"]
                            self.new_hosts[n["host"]].services[
                                new_service].attempt = n["attempt"]
                            self.new_hosts[n["host"]].services[
                                new_service].status_information = n[
                                    "status_information"]
                            self.new_hosts[n["host"]].services[
                                new_service].passiveonly = False
                            self.new_hosts[n["host"]].services[
                                new_service].flapping = False
                            self.new_hosts[n["host"]].services[
                                new_service].site = n["site"]
                            self.new_hosts[n["host"]].services[
                                new_service].address = n["host"]
                            self.new_hosts[n["host"]].services[
                                new_service].command = n["command"]
                            self.new_hosts[n["host"]].services[
                                new_service].triggerid = n["triggerid"]

        except (ZabbixError, ZabbixAPIException):
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)

        return ret
Esempio n. 9
0
    def _get_status(self):
        """
        Get status from op5 Monitor Server
        """
        # create Nagios items dictionary with to lists for services and hosts
        # every list will contain a dictionary for every failed service/host
        # this dictionary is only temporarily
        nagitems = {"hosts": [], "services": []}

        # new_hosts dictionary
        self.new_hosts = dict()

        # Fetch api listview with filters
        try:

            # Fetch Host info
            api_default_host_query = '[hosts] %s ' % self.host_filter
            api_default_host_query += '&columns=%s' % (','.join(
                self.api_host_col))
            api_default_host_query += '&format=json'

            api_default_host_query = api_default_host_query.replace(" ", "%20")
            result = self.FetchURL(self.monitor_url + self.api_count +
                                   api_default_host_query,
                                   giveback="raw")
            data, error, status_code = json.loads(result.result),\
                                       result.error,\
                                       result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            # if there are errors return them
            if errors_occured != False:
                return (errors_occured)

            if data['count']:
                count = data['count']
                api_default_host_query = '[hosts] %s ' % self.host_filter
                api_default_host_query += '&columns=%s' % (','.join(
                    self.api_host_col))
                api_default_host_query += '&format=json'

                api_default_host_query = api_default_host_query.replace(
                    " ", "%20")
                result = self.FetchURL(self.monitor_url + self.api_query +
                                       api_default_host_query + '&limit=' +
                                       str(count),
                                       giveback="raw")
                data = json.loads(result.result)
                n = dict()
                for api in data:
                    n['host'] = api['name']
                    n["acknowledged"] = api['acknowledged']
                    n["flapping"] = api['is_flapping']
                    n["notifications_disabled"] = 0 if api[
                        'notifications_enabled'] else 1
                    n["passiveonly"] = 0 if api['active_checks_enabled'] else 1
                    n["scheduled_downtime"] = 1 if api[
                        'scheduled_downtime_depth'] else 0
                    n['attempt'] = "%s/%s" % (str(api['current_attempt']),
                                              str(api['max_check_attempts']))
                    n['duration'] = human_duration(api['last_state_change'])
                    n['last_check'] = datetime.fromtimestamp(
                        int(api['last_check'])).strftime('%Y-%m-%d %H:%M:%S')
                    n['status'] = self.STATUS_HOST_MAPPING[str(api['state'])]
                    n['status_information'] = api['plugin_output']
                    n['status_type'] = api['state']

                    if not n['host'] in self.new_hosts:
                        self.new_hosts[n['host']] = GenericHost()
                        self.new_hosts[n['host']].name = n['host']
                        self.new_hosts[
                            n['host']].acknowledged = n["acknowledged"]
                        self.new_hosts[n['host']].attempt = n['attempt']
                        self.new_hosts[n['host']].duration = n['duration']
                        self.new_hosts[n['host']].flapping = n["flapping"]
                        self.new_hosts[n['host']].last_check = n['last_check']
                        self.new_hosts[n['host']].notifications_disabled = n[
                            "notifications_disabled"]
                        self.new_hosts[
                            n['host']].passiveonly = n["passiveonly"]
                        self.new_hosts[n['host']].scheduled_downtime = n[
                            "scheduled_downtime"]
                        self.new_hosts[n['host']].status = n['status']
                        self.new_hosts[n['host']].status_information = n[
                            'status_information'].replace("\n", " ").strip()
                        self.new_hosts[
                            n['host']].status_type = n['status_type']
                    nagitems['hosts'].append(n)
                del n

            # Fetch services info
            api_default_svc_query = '[services] %s ' % self.service_filter
            api_default_svc_query += '&columns=%s' % (','.join(
                self.api_svc_col))
            api_default_svc_query += '&format=json'

            api_default_svc_query = api_default_svc_query.replace(" ", "%20")
            result = self.FetchURL(self.monitor_url + self.api_count +
                                   api_default_svc_query,
                                   giveback="raw")
            data, error, status_code = json.loads(result.result),\
                                       result.error,\
                                       result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            # if there are errors return them
            if errors_occured != False:
                return (errors_occured)

            if data['count']:
                count = data['count']
                api_default_svc_query = '[services] %s ' % self.service_filter
                api_default_svc_query += '&columns=%s' % (','.join(
                    self.api_svc_col))
                api_default_svc_query += '&format=json'

                api_default_svc_query = api_default_svc_query.replace(
                    " ", "%20")
                result = self.FetchURL(self.monitor_url + self.api_query +
                                       api_default_svc_query + '&limit=' +
                                       str(count),
                                       giveback="raw")
                data = json.loads(result.result)
                for api in data:
                    n = dict()
                    n['host'] = api['host']['name']
                    n['status'] = self.STATUS_HOST_MAPPING[str(
                        api['host']['state'])]
                    n["passiveonly"] = 0 if api['host'][
                        'active_checks_enabled'] else 1

                    if not n['host'] in self.new_hosts:
                        self.new_hosts[n['host']] = GenericHost()
                        self.new_hosts[n['host']].name = n['host']
                        self.new_hosts[n['host']].status = n['status']
                        self.new_hosts[
                            n['host']].passiveonly = n["passiveonly"]

                    n['service'] = api['description']
                    n["acknowledged"] = api['acknowledged']
                    n["flapping"] = api['is_flapping']
                    n["notifications_disabled"] = 0 if api[
                        'notifications_enabled'] else 1
                    n["passiveonly"] = 0 if api['active_checks_enabled'] else 1
                    n["scheduled_downtime"] = 1 if api[
                        'scheduled_downtime_depth'] or api['host'][
                            'scheduled_downtime_depth'] else 0
                    n['attempt'] = "%s/%s" % (str(api['current_attempt']),
                                              str(api['max_check_attempts']))
                    n['duration'] = human_duration(api['last_state_change'])
                    n['last_check'] = datetime.fromtimestamp(
                        int(api['last_check'])).strftime('%Y-%m-%d %H:%M:%S')
                    n['status_information'] = api['plugin_output']

                    if not n['host'] in self.new_hosts:
                        self.new_hosts[n['host']] = GenericHost()
                        self.new_hosts[n['host']].name = n['host']
                        self.new_hosts[n['host']].status = n['status']

                    if not n['service'] in self.new_hosts[n['host']].services:
                        n['status'] = self.STATUS_SVC_MAPPING[str(
                            api['state'])]

                        self.new_hosts[n['host']].services[
                            n['service']] = GenericService()
                        self.new_hosts[n['host']].services[
                            n['service']].acknowledged = n['acknowledged']
                        self.new_hosts[n['host']].services[
                            n['service']].attempt = n['attempt']
                        self.new_hosts[n['host']].services[
                            n['service']].duration = n['duration']
                        self.new_hosts[n['host']].services[
                            n['service']].flapping = n['flapping']
                        self.new_hosts[n['host']].services[
                            n['service']].host = n['host']
                        self.new_hosts[n['host']].services[
                            n['service']].last_check = n['last_check']
                        self.new_hosts[n['host']].services[
                            n['service']].name = n['service']
                        self.new_hosts[n['host']].services[
                            n['service']].notifications_disabled = n[
                                "notifications_disabled"]
                        self.new_hosts[n['host']].services[
                            n['service']].passiveonly = n['passiveonly']
                        self.new_hosts[n['host']].services[
                            n['service']].scheduled_downtime = n['duration']
                        self.new_hosts[n['host']].services[
                            n['service']].scheduled_downtime = n[
                                'scheduled_downtime']
                        self.new_hosts[n['host']].services[
                            n['service']].status = n['status']
                        self.new_hosts[n['host']].services[
                            n['service']].status_information = n[
                                'status_information'].replace("\n",
                                                              " ").strip()

                    nagitems['services'].append(n)
                return Result()
        except:

            self.isChecking = False
            # store status_code for returning result to tell GUI to reauthenticate
            status_code = result.status_code

            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error, status_code=status_code)

        return Result()
Esempio n. 10
0
    def _get_status_JSON(self):
        """
            Get status from Icinga Server - the JSON way
        """
        # new_hosts dictionary
        self.new_hosts = dict()

        # hosts - mostly the down ones
        # now using JSON output from Icinga
        try:
            for status_type in 'hard', 'soft':
                result = self.FetchURL(self.cgiurl_hosts[status_type],
                                       giveback='raw')
                # purify JSON result of unnecessary control sequence \n
                jsonraw, error, status_code = copy.deepcopy(result.result.replace('\n', '')),\
                                              copy.deepcopy(result.error),\
                                              result.status_code

                # check if any error occured
                errors_occured = self.check_for_error(jsonraw, error,
                                                      status_code)
                # if there are errors return them
                if errors_occured != False:
                    return (errors_occured)

                jsondict = json.loads(jsonraw)
                hosts = copy.deepcopy(jsondict['status']['host_status'])

                for host in hosts:
                    # make dict of tuples for better reading
                    h = dict(host.items())

                    # host
                    if self.use_display_name_host == False:
                        # according to http://sourceforge.net/p/nagstamon/bugs/83/ it might
                        # better be host_name instead of host_display_name
                        # legacy Icinga adjustments
                        if 'host_name' in h:
                            host_name = h['host_name']
                        elif 'host' in h:
                            host_name = h['host']
                    else:
                        # https://github.com/HenriWahl/Nagstamon/issues/46 on the other hand has
                        # problems with that so here we go with extra display_name option
                        host_name = h['host_display_name']

                    # host objects contain service objects
                    if not host_name in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].server = self.name
                        self.new_hosts[host_name].status = h['status']
                        self.new_hosts[host_name].last_check = h['last_check']
                        self.new_hosts[host_name].duration = h['duration']
                        self.new_hosts[host_name].attempt = h['attempts']
                        self.new_hosts[host_name].status_information = h[
                            'status_information'].replace('\n', ' ').strip()
                        self.new_hosts[host_name].passiveonly = not (
                            h['active_checks_enabled'])
                        self.new_hosts[
                            host_name].notifications_disabled = not (
                                h['notifications_enabled'])
                        self.new_hosts[host_name].flapping = h['is_flapping']
                        self.new_hosts[host_name].acknowledged = h[
                            'has_been_acknowledged']
                        self.new_hosts[host_name].scheduled_downtime = h[
                            'in_scheduled_downtime']
                        self.new_hosts[host_name].status_type = status_type

                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs host_description and no display name
                        self.new_hosts[host_name].real_name = h['host_name']

                    del h, host_name
        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            for status_type in 'hard', 'soft':
                result = self.FetchURL(self.cgiurl_services[status_type],
                                       giveback='raw')
                # purify JSON result of unnecessary control sequence \n
                jsonraw, error, status_code = copy.deepcopy(result.result.replace('\n', '')),\
                                              copy.deepcopy(result.error),\
                                              result.status_code

                # check if any error occured
                errors_occured = self.check_for_error(jsonraw, error,
                                                      status_code)
                # if there are errors return them
                if errors_occured != False:
                    return (errors_occured)

                jsondict = json.loads(jsonraw)
                services = copy.deepcopy(jsondict['status']['service_status'])

                for service in services:
                    # make dict of tuples for better reading
                    s = dict(service.items())

                    if self.use_display_name_host == False:
                        # according to http://sourceforge.net/p/nagstamon/bugs/83/ it might
                        # better be host_name instead of host_display_name
                        # legacy Icinga adjustments
                        if 'host_name' in s: host_name = s['host_name']
                        elif 'host' in s: host_name = s['host']
                    else:
                        # https://github.com/HenriWahl/Nagstamon/issues/46 on the other hand has
                        # problems with that so here we go with extra display_name option
                        host_name = s['host_display_name']

                    # host objects contain service objects
                    if not host_name in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].status = 'UP'
                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs host_description and no display name
                        self.new_hosts[host_name].real_name = s['host_name']

                    if self.use_display_name_host == False:
                        # legacy Icinga adjustments
                        if 'service_description' in s:
                            service_name = s['service_description']
                        elif 'description' in s:
                            service_name = s['description']
                        elif 'service' in s:
                            service_name = s['service']
                    else:
                        service_name = s['service_display_name']

                    # if a service does not exist create its object
                    if not service_name in self.new_hosts[host_name].services:
                        self.new_hosts[host_name].services[
                            service_name] = GenericService()
                        self.new_hosts[host_name].services[
                            service_name].host = host_name
                        self.new_hosts[host_name].services[
                            service_name].name = service_name
                        self.new_hosts[host_name].services[
                            service_name].server = self.name
                        self.new_hosts[host_name].services[
                            service_name].status = s['status']
                        self.new_hosts[host_name].services[
                            service_name].last_check = s['last_check']
                        self.new_hosts[host_name].services[
                            service_name].duration = s['duration']
                        self.new_hosts[host_name].services[
                            service_name].attempt = s['attempts']
                        self.new_hosts[host_name].services[
                            service_name].status_information = s[
                                'status_information'].replace('\n',
                                                              ' ').strip()
                        self.new_hosts[host_name].services[
                            service_name].passiveonly = not (
                                s['active_checks_enabled'])
                        self.new_hosts[host_name].services[
                            service_name].notifications_disabled = not (
                                s['notifications_enabled'])
                        self.new_hosts[host_name].services[
                            service_name].flapping = s['is_flapping']
                        self.new_hosts[host_name].services[
                            service_name].acknowledged = s[
                                'has_been_acknowledged']
                        self.new_hosts[host_name].services[
                            service_name].scheduled_downtime = s[
                                'in_scheduled_downtime']
                        self.new_hosts[host_name].services[
                            service_name].status_type = status_type

                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs service_description and no display name
                        self.new_hosts[host_name].services[
                            service_name].real_name = s['service_description']

                    del s, host_name, service_name

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # some cleanup
        del jsonraw, jsondict, error, hosts, services

        # dummy return in case all is OK
        return Result()
Esempio n. 11
0
    def _get_status(self):
        """
            Get status from Zabbix Server
        """

        # Login to ZabbixAPI
        self._login()

        # =========================================
        # problems
        # =========================================
        problems = []
        try:
            #Get all current problems (trigger based)
            problems = self.zapi.problem.get({'recent': False})

            for problem in problems:

                #get trigger which rose current problem
                trigger = self.zapi.trigger.get({'triggerids': problem['objectid'],
                                                'monitored': True,
                                                'active': True,
                                                'skipDependent': True,
                                                'selectHosts': ['hostid', 'name', 'maintenance_status',
                                                                'available', 'error', 'errors_from',
                                                                'ipmi_available', 'ipmi_error', 'ipmi_errors_from',
                                                                'jmx_available', 'jmx_error', 'jmx_errors_from',
                                                                'snmp_available', 'snmp_error', 'snmp_errors_from'],
                                                'selectItems': ['key_', 'lastclock']})


                #problems on disabled/maintenance/deleted hosts don't have triggers
                #have to do that because of how zabbix housekeeping service work
                #API reports past problems for hosts that no longer exist
                if not trigger:
                    continue

                service_id = problem['eventid']
                host_id = trigger[0]['hosts'][0]['hostid']

                #new host to report, we only need to do that at first problem for that host
                if host_id not in self.new_hosts:
                    self.new_hosts[host_id] = GenericHost()
                    self.new_hosts[host_id].name = trigger[0]['hosts'][0]['name']

                    #host has active maintenance period
                    if trigger[0]['hosts'][0]['maintenance_status'] == "1":
                        self.new_hosts[host_id].scheduled_downtime = True

                    #host not available via agent
                    if trigger[0]['hosts'][0]['available'] == "2":
                        self.new_hosts[host_id].status = "DOWN"
                        self.new_hosts[host_id].status_information = trigger[0]['hosts'][0]['error']
                        self.new_hosts[host_id].duration = HumanReadableDurationFromTimestamp(trigger[0]['hosts'][0]['errors_from'])

                    #host not available via ipmi
                    if trigger[0]['hosts'][0]['ipmi_available'] == "2":
                        self.new_hosts[host_id].status = "DOWN"
                        self.new_hosts[host_id].status_information = trigger[0]['hosts'][0]['ipmi_error']
                        self.new_hosts[host_id].duration = HumanReadableDurationFromTimestamp(trigger[0]['hosts'][0]['ipmi_errors_from'])

                    #host not available via jmx
                    if trigger[0]['hosts'][0]['jmx_available'] == "2":
                        self.new_hosts[host_id].status = "DOWN"
                        self.new_hosts[host_id].status_information = trigger[0]['hosts'][0]['jmx_error']
                        self.new_hosts[host_id].duration = HumanReadableDurationFromTimestamp(trigger[0]['hosts'][0]['jmx_errors_from'])

                    #host not available via snmp
                    if trigger[0]['hosts'][0]['snmp_available'] == "2":
                        self.new_hosts[host_id].status = "DOWN"
                        self.new_hosts[host_id].status_information = trigger[0]['hosts'][0]['snmp_error']
                        self.new_hosts[host_id].duration = HumanReadableDurationFromTimestamp(trigger[0]['hosts'][0]['snmp_errors_from'])

                #service to report
                self.new_hosts[host_id].services[service_id] = GenericService()
                self.new_hosts[host_id].services[service_id].host = trigger[0]['hosts'][0]['name']
                self.new_hosts[host_id].services[service_id].status = self.statemap.get(problem['severity'], problem['severity'])
                self.new_hosts[host_id].services[service_id].duration = HumanReadableDurationFromTimestamp(problem['clock'])
                self.new_hosts[host_id].services[service_id].name = trigger[0]['items'][0]['key_']
                self.new_hosts[host_id].services[service_id].last_check = time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(int(trigger[0]['items'][0]['lastclock'])))

                #we add opdata to status information just like in zabbix GUI
                if problem["opdata"] != "":
                    self.new_hosts[host_id].services[service_id].status_information = problem['name'] + " (" + problem["opdata"] + ")"
                else:
                    self.new_hosts[host_id].services[service_id].status_information = problem['name']

                #service is acknowledged
                if problem['acknowledged'] == "1":
                    self.new_hosts[host_id].services[service_id].acknowledged = True

        except (ZabbixAPIException):
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)

        return Result()
Esempio n. 12
0
    def _get_status(self):
        """
        Get status from Alertmanager Server
        """
        if conf.debug_mode:
            self.Debug(
                server=self.get_name(),
                debug="detection config (map_to_status_information): '" +
                str(self.map_to_status_information) + "'")
            self.Debug(server=self.get_name(),
                       debug="detection config (map_to_hostname): '" +
                       str(self.map_to_hostname) + "'")
            self.Debug(server=self.get_name(),
                       debug="detection config (map_to_servicename): '" +
                       str(self.map_to_servicename) + "'")

        # get all alerts from the API server
        try:
            result = self.FetchURL(self.monitor_url + self.API_PATH_ALERTS,
                                   giveback="raw")

            if conf.debug_mode:
                self.Debug(server=self.get_name(),
                           debug="received status code '" +
                           str(result.status_code) +
                           "' with this content in result.result: \n\
-----------------------------------------------------------------------------------------------------------------------------\n\
" + result.result + "\
-----------------------------------------------------------------------------------------------------------------------------"
                           )

            data = json.loads(result.result)
            error = result.error
            status_code = result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            if errors_occured is not False:
                return (errors_occured)

            for alert in data:
                if conf.debug_mode:
                    self.Debug(server=self.get_name(),
                               debug="processing alert with fingerprint '" +
                               alert['fingerprint'] + "':")

                labels = alert.get("labels", {})

                # skip alerts with none severity
                severity = labels.get("severity", "UNKNOWN").upper()

                if severity == "NONE":
                    if conf.debug_mode:
                        self.Debug(server=self.get_name(),
                                   debug="[" + alert['fingerprint'] +
                                   "]: detected severity from labels '" +
                                   severity + "' -> skipping alert")
                    continue

                if conf.debug_mode:
                    self.Debug(server=self.get_name(),
                               debug="[" + alert['fingerprint'] +
                               "]: detected severity from labels '" +
                               severity + "'")

                hostname = "unknown"
                for host_label in self.map_to_hostname.split(','):
                    if host_label in labels:
                        hostname = labels.get(host_label)
                        break

                if conf.debug_mode:
                    self.Debug(server=self.get_name(),
                               debug="[" + alert['fingerprint'] +
                               "]: detected hostname from labels: '" +
                               hostname + "'")

                servicename = "unknown"
                for service_label in self.map_to_servicename.split(','):
                    if service_label in labels:
                        servicename = labels.get(service_label)
                        break

                if conf.debug_mode:
                    self.Debug(server=self.get_name(),
                               debug="[" + alert['fingerprint'] +
                               "]: detected servicename from labels: '" +
                               servicename + "'")

                service = PrometheusService()
                service.host = str(hostname)
                service.name = servicename
                service.server = self.name
                service.status = severity
                service.last_check = str(self._get_duration(
                    alert["updatedAt"]))

                if "status" in alert:
                    service.attempt = alert["status"].get("state", "unknown")
                else:
                    service.attempt = "unknown"

                if service.attempt == "suppressed":
                    service.scheduled_downtime = True
                    if conf.debug_mode:
                        self.Debug(server=self.get_name(),
                                   debug="[" + alert['fingerprint'] +
                                   "]: detected status: '" + service.attempt +
                                   "' -> interpreting as silenced")
                else:
                    if conf.debug_mode:
                        self.Debug(server=self.get_name(),
                                   debug="[" + alert['fingerprint'] +
                                   "]: detected status: '" + service.attempt +
                                   "'")

                service.duration = str(self._get_duration(alert["startsAt"]))

                # Alertmanager specific extensions
                service.generatorURL = alert.get("generatorURL", {})
                service.fingerprint = alert.get("fingerprint", {})

                annotations = alert.get("annotations", {})
                status_information = ""
                for status_information_label in self.map_to_status_information.split(
                        ','):
                    if status_information_label in annotations:
                        status_information = annotations.get(
                            status_information_label)
                        break
                service.status_information = status_information

                if hostname not in self.new_hosts:
                    self.new_hosts[hostname] = GenericHost()
                    self.new_hosts[hostname].name = str(hostname)
                    self.new_hosts[hostname].server = self.name
                self.new_hosts[hostname].services[servicename] = service

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # dummy return in case all is OK
        return Result()
Esempio n. 13
0
    def _get_status(self):
        """
            Get status from Thruk Server
        """
        # new_hosts dictionary
        self.new_hosts = dict()

        # hosts - mostly the down ones
        # unfortunately the hosts status page has a different structure so
        # hosts must be analyzed separately
        try:
            # JSON experiments
            result = self.FetchURL(self.cgiurl_hosts, giveback='raw')
            jsonraw, error, status_code = copy.deepcopy(result.result),\
                                          copy.deepcopy(result.error),\
                                          result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(jsonraw, error, status_code)
            # if there are errors return them
            if errors_occured != False:
                return(errors_occured)

            # in case basic auth did not work try form login cookie based login
            if jsonraw.startswith("<"):
                self.refresh_authentication = True
                return Result(result=None, error="Login failed")

            # in case JSON is not empty evaluate it
            elif not jsonraw == "[]":
                hosts = json.loads(jsonraw)

                for h in hosts:
                    if h["name"] not in self.new_hosts:
                        self.new_hosts[h["name"]] = GenericHost()
                        self.new_hosts[h["name"]].name = h["name"]
                        self.new_hosts[h["name"]].server = self.name
                        self.new_hosts[h["name"]].status = self.STATES_MAPPING["hosts"][h["state"]]
                        self.new_hosts[h["name"]].last_check = datetime.datetime.fromtimestamp(int(h["last_check"])).isoformat(" ")
                        self.new_hosts[h["name"]].duration = HumanReadableDurationFromTimestamp(h["last_state_change"])
                        self.new_hosts[h["name"]].attempt = "%s/%s" % (h["current_attempt"], h["max_check_attempts"])
                        self.new_hosts[h["name"]].status_information = h["plugin_output"].replace("\n", " ").strip()
                        self.new_hosts[h["name"]].passiveonly = not(bool(int(h["active_checks_enabled"])))
                        self.new_hosts[h["name"]].notifications_disabled = not(bool(int(h["notifications_enabled"])))
                        self.new_hosts[h["name"]].flapping = bool(int(h["is_flapping"]))
                        self.new_hosts[h["name"]].acknowledged = bool(int(h["acknowledged"]))
                        self.new_hosts[h["name"]].scheduled_downtime = bool(int(h["scheduled_downtime_depth"]))
                        self.new_hosts[h["name"]].status_type = {0: "soft", 1: "hard"}[h["state_type"]]
                    del h
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            # JSON experiments
            result = self.FetchURL(self.cgiurl_services, giveback="raw")
            jsonraw, error, status_code = copy.deepcopy(result.result),\
                                          copy.deepcopy(result.error),\
                                          result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(jsonraw, error, status_code)
            # if there are errors return them
            if errors_occured != False:
                return(errors_occured)

            # in case basic auth did not work try form login cookie based login
            if jsonraw.startswith("<"):
                self.refresh_authentication = True
                return Result(result=None, error="Login failed")

            # in case JSON is not empty evaluate it
            elif not jsonraw == "[]":
                services = json.loads(jsonraw)

                for s in services:
                    # host objects contain service objects
                    if s["host_name"] not in self.new_hosts:
                        self.new_hosts[s["host_name"]] = GenericHost()
                        self.new_hosts[s["host_name"]].name = s["host_name"]
                        self.new_hosts[s["host_name"]].server = self.name
                        self.new_hosts[s["host_name"]].status = "UP"

                    # if a service does not exist create its object
                    if s["description"] not in self.new_hosts[s["host_name"]].services:
                        # ##new_service = s["description"]
                        self.new_hosts[s["host_name"]].services[s["description"]] = GenericService()
                        self.new_hosts[s["host_name"]].services[s["description"]].host = s["host_name"]
                        self.new_hosts[s["host_name"]].services[s["description"]].name = s["description"]
                        self.new_hosts[s["host_name"]].services[s["description"]].server = self.name
                        self.new_hosts[s["host_name"]].services[s["description"]].status = self.STATES_MAPPING["services"][s["state"]]
                        self.new_hosts[s["host_name"]].services[s["description"]].last_check = datetime.datetime.fromtimestamp(int(s["last_check"])).isoformat(" ")
                        self.new_hosts[s["host_name"]].services[s["description"]].duration = HumanReadableDurationFromTimestamp(s["last_state_change"])
                        self.new_hosts[s["host_name"]].services[s["description"]].attempt = "%s/%s" % (s["current_attempt"], s["max_check_attempts"])
                        self.new_hosts[s["host_name"]].services[s["description"]].status_information = s["plugin_output"].replace("\n", " ").strip()
                        self.new_hosts[s["host_name"]].services[s["description"]].passiveonly = not(bool(int(s["active_checks_enabled"])))
                        self.new_hosts[s["host_name"]].services[s["description"]].notifications_disabled = not(bool(int(s["notifications_enabled"])))
                        self.new_hosts[s["host_name"]].services[s["description"]].flapping = not(bool(int(s["notifications_enabled"])))
                        self.new_hosts[s["host_name"]].services[s["description"]].acknowledged = bool(int(s["acknowledged"]))
                        self.new_hosts[s["host_name"]].services[s["description"]].scheduled_downtime = bool(int(s["scheduled_downtime_depth"]))
                        self.new_hosts[s["host_name"]].services[s["description"]].status_type = {0: "soft", 1: "hard"}[s["state_type"]]
                        del s
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # dummy return in case all is OK
        return Result()
Esempio n. 14
0
    def _get_status(self):
        """
            Get status from monitos4 Server - only JSON
        """
        # define CGI URLs for hosts and services
        if self.cgiurl_hosts == None:
            # hosts (up, down, unreachable or pending)
            # https://locmos41xsupport/rest/private/nagios/host 
            if self.use_autologin == True:
                self.cgiurl_hosts = self.monitor_cgi_url + '/rest/private/nagios/host' + '?authtoken=' + self.autologin_key
            else:
                self.cgiurl_hosts = self.monitor_cgi_url + '/rest/private/nagios/host'

            if conf.debug_mode == True:
                self.Debug(server=self.get_name(), debug='cgiurl_hosts is: ' + self.cgiurl_hosts)

        if self.cgiurl_services == None:
            # services (warning, critical, unknown or pending)
            # https://locmos41xsupport/rest/private/nagios/service_status/browser 
            if self.use_autologin == True:
                self.cgiurl_services = self.monitor_cgi_url + \
                                   '/rest/private/nagios/service_status/browser' + '?authtoken=' + self.autologin_key
            else:
                self.cgiurl_services = self.monitor_cgi_url + \
                                   '/rest/private/nagios/service_status/browser'

            if conf.debug_mode == True:
                self.Debug(server=self.get_name(), debug='cgiurl_services is: ' + self.cgiurl_services)

        self.new_hosts = dict()

        if conf.debug_mode == True:
            self.Debug(server=self.get_name(), debug='monitos4 Authtoken is: ' + self.autologin_key)

        # hostlist
        try:
            form_data = dict()
            form_data['acknowledged'] = 1
            form_data['downtime'] = 1
            form_data['inactiveHosts'] = 0
            form_data['disabledNotification'] = 1
            form_data['limit_start'] = 0
            # Get all hosts
            form_data['limit_length'] = 99999
            # 2018_11_18, studo, fetch only hostproblems
            #form_data['filter[0][data][type]'] = 'list'
            #form_data['filter[0][data][value]'] = '1,2,4'
            #form_data['filter[0][field]'] = 'sv_host__nagios_status__current_state'
            #if self.use_autologin == True:
            #    form_data['authtoken'] = self.autologin_key

            result = self.FetchURL(
                self.cgiurl_hosts, giveback='raw', cgi_data=form_data)

            # authentication errors get a status code 200 too
            if result.status_code < 400 and \
                    result.result.startswith('<'):
                # in case of auth error reset HTTP session and try again
                self.reset_HTTP()
                result = self.FetchURL(
                    self.cgiurl_hosts, giveback='raw', cgi_data=form_data)

                if result.status_code < 400 and \
                        result.result.startswith('<'):
                    self.refresh_authentication = True
                    return Result(result=result.result,
                                  error='Authentication error',
                                  status_code=result.status_code)

            # purify JSON result
            jsonraw = copy.deepcopy(result.result.replace('\n', ''))
            error = copy.deepcopy(result.error)
            status_code = result.status_code

            if error != '' or status_code >= 400:
                return Result(result=jsonraw,
                              error=error,
                              status_code=status_code)

            self.check_for_error(jsonraw, error, status_code)

            hosts = json.loads(jsonraw)

            for host in hosts['data']:
                h = dict(host)

                # Skip if Host is 'Pending'
                # 2018_04_10
                try:
                    if type(h['sv_host__nagios_status__current_state']) is int and int(h['sv_host__nagios_status__current_state']) == 4:
                        continue
                except:
                    pass

                # hostlist
                host_name = h['sv_host__nagios__host_name']
                current_host_state = h['sv_host__nagios_status__current_state']
                #2018_11_18: debugging
                if conf.debug_mode:
                    self.Debug(server=self.get_name(), debug=time.strftime('%a %H:%M:%S') + ' host ' + host_name + ' has current_state ' + str(current_host_state))

                # If a host does not exist, create its object
                if host_name not in self.new_hosts:
                    self.new_hosts[host_name] = GenericHost()
                    self.new_hosts[host_name].name = host_name
                    self.new_hosts[host_name].svid = h['sv_host__svobjects____SVID']
                    self.new_hosts[host_name].server = self.name
                    try:
                        self.new_hosts[host_name].status = self.STATES_MAPPING['hosts'][int(h['sv_host__nagios_status__current_state'])]
                    except:
                        pass
                    try:
                        self.new_hosts[host_name].last_check = datetime.datetime.fromtimestamp( int(h['sv_host__nagios_status__last_check']))
                    except:
                        pass
                    self.new_hosts[host_name].attempt = h['sv_host__nagios__max_check_attempts']
                    self.new_hosts[host_name].status_information = h['sv_host__nagios_status__plugin_output']
                    
                    if type(h['sv_host__nagios_status__checks_enabled']) is int:
                        self.new_hosts[host_name].passiveonly = not (int(h['sv_host__nagios_status__checks_enabled']))
                    if type(h['sv_host__nagios_status__is_flapping']) is int:
                        if int(h['sv_host__nagios_status__is_flapping']) != 0:
                            self.new_hosts[host_name].flapping = True
                    # 2017_11_06
                    if type(h['sv_host__nagios_status__problem_has_been_acknowledged']) is int:
                        if int(h['sv_host__nagios_status__problem_has_been_acknowledged']) != 0:
                            self.new_hosts[host_name].acknowledged = True
                    # 2017_11_06
                    try:
                        if int(h['sv_host__nagios_status__scheduled_downtime_depth']) != 0:
                            self.new_hosts[host_name].scheduled_downtime = True
                    except:
                        self.new_hosts[host_name].scheduled_downtime = False
                        
                    # 2017_11_06 Skip if Host has notifications disabled
                    try:
                        if int(h['sv_host__nagios_status__notifications_enabled']) == 0:
                            self.new_hosts[host_name].notifications_disabled = True
                    except:
                        self.new_hosts[host_name].notifications_disabled = False

                    try:
                        self.new_hosts[host_name].status_type = 'soft' if int(h['sv_host__nagios_status__state_type']) == 0 else 'hard'
                    except:
                        self.new_hosts[host_name].status_type = 'hard'

                    # extra duration needed for calculation
                    duration = datetime.datetime.now() - datetime.datetime.fromtimestamp(int(h['sv_host__nagios_status__last_state_change']))

                    self.new_hosts[host_name].duration = strfdelta( duration, '{days}d {hours}h {minutes}m {seconds}s')

                del h, host_name
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # servicelist
        # 2018_03_27
        # https://locmos41xsupport/rest/private/nagios/service_status/browser
        #filter[0][data][type]   list
        #filter[0][data][value]  0,1,2,4
        #filter[0][field]    sv_host__nagios_status__current_state
        #filter[1][data][type]   list
        #filter[1][data][value]  1,2,3,4
        #filter[1][field]    sv_service_status__nagios_status__current_state
        try:
            form_data = dict()
            form_data['acknowledged'] = 1
            form_data['downtime'] = 1
            form_data['inactiveHosts'] = 0
            form_data['disabledNotification'] = 1
            form_data['softstate'] = 1
            form_data['limit_start'] = 0
            # Get all services
            form_data['limit_length'] = 99999
            # 2018_11_18, studo, fetch only serviceproblems
            form_data['filter[0][data][type]'] = 'list'
            form_data['filter[0][data][value]'] = '0,1,2,4'
            form_data['filter[0][field]'] = 'sv_host__nagios_status__current_state'
            form_data['filter[1][data][type]'] = 'list'
            form_data['filter[1][data][value]'] = '1,2,3,4'
            form_data['filter[1][field]'] = 'sv_service_status__nagios_status__current_state'
            #if self.use_autologin == True:
            #    form_data['authtoken'] = self.autologin_key

            result = self.FetchURL(self.cgiurl_services,
                                   giveback='raw', cgi_data=form_data)

            # purify JSON result
            jsonraw = copy.deepcopy(result.result.replace('\n', ''))
            error = copy.deepcopy(result.error)
            status_code = result.status_code

            if error != '' or status_code >= 400:
                return Result(result=jsonraw,
                              error=error,
                              status_code=status_code)

            self.check_for_error(jsonraw, error, status_code)

            services = json.loads(jsonraw)

            for service in services['data']:
                s = dict(service)

                # Skip if Host or Service is 'Pending'
                if int(s['sv_service_status__nagios_status__current_state']) == 4 or int(
                        s['sv_host__nagios_status__current_state']) == 4:
                    continue

                # host and service
                # 2017_11_09, this is a hack
                host_name = s['sv_host__nagios__host_name']
                service_name = s['sv_service_status__nagios__service_description']
                # service_name = s['sv_service_status__svobjects__rendered_label']
                display_name = s['sv_service_status__nagios__service_description']
                current_service_state = s['sv_service_status__nagios_status__current_state']

                #2018_11_18: debugging
                if conf.debug_mode:
                    self.Debug(server=self.get_name(), debug=time.strftime('%a %H:%M:%S') + ' Service ' + host_name + '!' + service_name + ' has current_state: ' + str(current_service_state) )

                # If a service does not exist, create its object
                if service_name not in self.new_hosts[host_name].services:
                    self.new_hosts[host_name].services[service_name] = GenericService(
                    )
                    self.new_hosts[host_name].services[service_name].host = host_name
                    self.new_hosts[host_name].services[service_name].svid = s['sv_service_status__svobjects____SVID']
                    self.new_hosts[host_name].services[service_name].name = display_name
                    # self.new_hosts[host_name].services[service_name].name = service_name
                    self.new_hosts[host_name].services[service_name].server = self.name
                    self.new_hosts[host_name].services[service_name].status = self.STATES_MAPPING['services'][int(
                        s['sv_service_status__nagios_status__current_state'])]
                    self.new_hosts[host_name].services[service_name].last_check = datetime.datetime.fromtimestamp(
                        int(s['sv_service_status__nagios_status__last_check']))
                    self.new_hosts[host_name].services[service_name].attempt = s[
                        'sv_service_status__nagios__max_check_attempts']
                    self.new_hosts[host_name].services[service_name].status_information = BeautifulSoup(
                        s['sv_service_status__nagios_status__plugin_output'].replace(
                            '\n', ' ').strip(),
                        'html.parser').text
                    self.new_hosts[host_name].services[service_name].passiveonly = not (
                        int(s['sv_service_status__nagios_status__checks_enabled']))
                    if int(s['sv_service_status__nagios_status__is_flapping']) != 0:
                        self.new_hosts[host_name].services[service_name].flapping = True
                    
                    # 2017_11_05
                    if int(s['sv_service_status__nagios_status__problem_has_been_acknowledged']) != 0:
                        self.new_hosts[host_name].services[service_name].acknowledged = True
                    # 2017_11_06
                    if int(s['sv_service_status__nagios_status__scheduled_downtime_depth']) != 0:
                        self.new_hosts[host_name].services[service_name].scheduled_downtime = True
                    # 2017_11_06 Skip if Host or Service has notifications disabled
                    if int(s['sv_service_status__nagios_status__notifications_enabled']) == 0 or int(s['sv_host__nagios_status__notifications_enabled']) == 0:
                        self.new_hosts[host_name].services[service_name].notifications_disabled = True
 

                    self.new_hosts[host_name].services[service_name].status_type = 'soft' if int(
                        s['sv_service_status__nagios_status__state_type']) == 0 else 'hard'

                    # acknowledge needs service_description and no display name
                    self.new_hosts[host_name].services[service_name].real_name = s[
                        'sv_service_status__nagios__service_description']

                    # extra duration needed for calculation
                    duration = datetime.datetime.now(
                    ) - datetime.datetime.fromtimestamp(
                        int(s['sv_service_status__nagios_status__last_state_change']))
                    self.new_hosts[host_name].services[service_name].duration = strfdelta(
                        duration, '{days}d {hours}h {minutes}m {seconds}s')

                del s, host_name, service_name
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        del jsonraw, error, hosts

        # dummy return in case all is OK
        return Result()
Esempio n. 15
0
    def _get_status(self):
        """
	        Get status from Prometheus Server
        """
        # get all alerts from the API server
        try:
            result = self.FetchURL(self.monitor_url + "/api/v1/alerts",
                                   giveback="raw")
            data, error, status_code = json.loads(
                result.result), result.error, result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            # if there are errors return them
            if errors_occured != False:
                return (errors_occured)

            if conf.debug_mode:
                self.Debug(server=self.get_name(),
                           debug="Fetched JSON: " + pprint.pformat(data))

            for alert in data["data"]["alerts"]:
                if conf.debug_mode:
                    self.Debug(server=self.get_name(),
                               debug="Processing Alert: " +
                               pprint.pformat(alert))

                if alert["labels"]["severity"] != "none":
                    if "pod_name" in alert["labels"]:
                        hostname = alert["labels"]["pod_name"]
                    elif "namespace" in alert["labels"]:
                        hostname = alert["labels"]["namespace"]
                    else:
                        hostname = "unknown"

                    self.new_hosts[hostname] = GenericHost()
                    self.new_hosts[hostname].name = str(hostname)
                    self.new_hosts[hostname].server = self.name

                    if "alertname" in alert["labels"]:
                        servicename = alert["labels"]["alertname"]
                    else:
                        servicename = "unknown"

                    self.new_hosts[hostname].services[
                        servicename] = PrometheusService()
                    self.new_hosts[hostname].services[servicename].host = str(
                        hostname)
                    self.new_hosts[hostname].services[
                        servicename].name = servicename
                    self.new_hosts[hostname].services[
                        servicename].server = self.name

                    self.new_hosts[hostname].services[
                        servicename].status = alert["labels"][
                            "severity"].upper()
                    self.new_hosts[hostname].services[
                        servicename].last_check = "n/a"
                    self.new_hosts[hostname].services[
                        servicename].attempt = alert["state"].upper()
                    self.new_hosts[hostname].services[
                        servicename].duration = str(
                            self._get_duration(alert["activeAt"]))
                    self.new_hosts[hostname].services[
                        servicename].status_information = alert["annotations"][
                            "message"].replace("\n", " ")

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        #dummy return in case all is OK
        return Result()
Esempio n. 16
0
    def _get_status(self):
        """
            Get status from Icinga Server - only JSON
        """
        # define CGI URLs for hosts and services
        if self.cgiurl_hosts == self.cgiurl_services == None:
            # services (unknown, warning or critical?)
            self.cgiurl_services = {'hard': self.monitor_cgi_url + '/monitoring/list/services?service_state>0&service_state<=3&service_state_type=1&addColumns=service_last_check&format=json', \
                                    'soft': self.monitor_cgi_url + '/monitoring/list/services?service_state>0&service_state<=3&service_state_type=0&addColumns=service_last_check&format=json'}
            # hosts (up or down or unreachable)
            self.cgiurl_hosts = {'hard': self.monitor_cgi_url + '/monitoring/list/hosts?host_state>0&host_state<=2&host_state_type=1&addColumns=host_last_check&format=json', \
                                 'soft': self.monitor_cgi_url + '/monitoring/list/hosts?host_state>0&host_state<=2&host_state_type=0&addColumns=host_last_check&format=json'}

        # new_hosts dictionary
        self.new_hosts = dict()

        # hosts - mostly the down ones
        # now using JSON output from Icinga
        try:
            for status_type in 'hard', 'soft':
                # first attempt
                result = self.FetchURL(self.cgiurl_hosts[status_type],
                                       giveback='raw')
                # authentication errors get a status code 200 too back because its
                # HTML works fine :-(
                if result.status_code < 400 and\
                   result.result.startswith('<'):
                    # in case of auth error reset HTTP session and try again
                    self.reset_HTTP()
                    result = self.FetchURL(self.cgiurl_hosts[status_type],
                                           giveback='raw')
                    # if it does not work again tell GUI there is a problem
                    if result.status_code < 400 and\
                       result.result.startswith('<'):
                        self.refresh_authentication = True
                        return Result(result=result.result,
                                      error='Authentication error',
                                      status_code=result.status_code)

                # purify JSON result of unnecessary control sequence \n
                jsonraw, error, status_code = copy.deepcopy(result.result.replace('\n', '')),\
                                              copy.deepcopy(result.error),\
                                              result.status_code

                if error != '' or status_code >= 400:
                    return Result(result=jsonraw,
                                  error=error,
                                  status_code=status_code)

                # check if any error occured
                self.check_for_error(jsonraw, error, status_code)

                hosts = json.loads(jsonraw)

                for host in hosts:
                    # make dict of tuples for better reading
                    h = dict(host.items())

                    # host
                    if self.use_display_name_host == False:
                        # according to http://sourceforge.net/p/nagstamon/bugs/83/ it might
                        # better be host_name instead of host_display_name
                        # legacy Icinga adjustments
                        if 'host_name' in h: host_name = h['host_name']
                        elif 'host' in h: host_name = h['host']
                    else:
                        # https://github.com/HenriWahl/Nagstamon/issues/46 on the other hand has
                        # problems with that so here we go with extra display_name option
                        host_name = h['host_display_name']

                    # host objects contain service objects
                    if not host_name in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].server = self.name
                        self.new_hosts[host_name].status = self.STATES_MAPPING[
                            'hosts'][int(h['host_state'])]
                        self.new_hosts[
                            host_name].last_check = datetime.datetime.fromtimestamp(
                                int(h['host_last_check']))
                        self.new_hosts[host_name].attempt = h['host_attempt']
                        self.new_hosts[
                            host_name].status_information = BeautifulSoup(
                                h['host_output'].replace('\n', ' ').strip(),
                                'html.parser').text
                        self.new_hosts[host_name].passiveonly = not (int(
                            h['host_active_checks_enabled']))
                        self.new_hosts[
                            host_name].notifications_disabled = not (int(
                                h['host_notifications_enabled']))
                        self.new_hosts[host_name].flapping = bool(
                            int(h['host_is_flapping']))
                        self.new_hosts[host_name].acknowledged = bool(
                            int(h['host_acknowledged']))
                        self.new_hosts[host_name].scheduled_downtime = bool(
                            int(h['host_in_downtime']))
                        self.new_hosts[host_name].status_type = status_type

                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs host_description and no display name
                        self.new_hosts[host_name].real_name = h['host_name']

                        # extra duration needed for calculation
                        duration = datetime.datetime.now(
                        ) - datetime.datetime.fromtimestamp(
                            int(h['host_last_state_change']))
                        self.new_hosts[host_name].duration = strfdelta(
                            duration, '{days}d {hours}h {minutes}m {seconds}s')

                    del h, host_name
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            for status_type in 'hard', 'soft':
                result = self.FetchURL(self.cgiurl_services[status_type],
                                       giveback='raw')
                # purify JSON result of unnecessary control sequence \n
                jsonraw, error, status_code = copy.deepcopy(result.result.replace('\n', '')),\
                                              copy.deepcopy(result.error),\
                                              result.status_code

                if error != '' or status_code >= 400:
                    return Result(result=jsonraw,
                                  error=error,
                                  status_code=status_code)

                # check if any error occured
                self.check_for_error(jsonraw, error, status_code)

                services = copy.deepcopy(json.loads(jsonraw))

                for service in services:
                    # make dict of tuples for better reading
                    s = dict(service.items())

                    if self.use_display_name_host == False:
                        # according to http://sourceforge.net/p/nagstamon/bugs/83/ it might
                        # better be host_name instead of host_display_name
                        # legacy Icinga adjustments
                        if 'host_name' in s: host_name = s['host_name']
                        elif 'host' in s: host_name = s['host']
                    else:
                        # https://github.com/HenriWahl/Nagstamon/issues/46 on the other hand has
                        # problems with that so here we go with extra display_name option
                        host_name = s['host_display_name']

                    # host objects contain service objects
                    if not host_name in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].status = 'UP'
                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs host_description and no display name
                        self.new_hosts[host_name].real_name = s['host_name']

                    #if self.use_display_name_host == False:
                    #    # legacy Icinga adjustments
                    #    if 'service_description' in s: service_name = s['service_description']
                    #    elif 'description' in s: service_name = s['description']
                    #    elif 'service' in s: service_name = s['service']
                    #else:
                    #    service_name = s['service_display_name']
                    # regarding to https://github.com/HenriWahl/Nagstamon/issues/400 Icinga2 needs no legacy adjustments
                    service_name = s['service_display_name']

                    # if a service does not exist create its object
                    if not service_name in self.new_hosts[host_name].services:
                        self.new_hosts[host_name].services[
                            service_name] = GenericService()
                        self.new_hosts[host_name].services[
                            service_name].host = host_name
                        self.new_hosts[host_name].services[
                            service_name].name = service_name
                        self.new_hosts[host_name].services[
                            service_name].server = self.name
                        self.new_hosts[host_name].services[
                            service_name].status = self.STATES_MAPPING[
                                'services'][int(s['service_state'])]
                        self.new_hosts[host_name].services[
                            service_name].last_check = datetime.datetime.fromtimestamp(
                                int(s['service_last_check']))
                        self.new_hosts[host_name].services[
                            service_name].attempt = s['service_attempt']
                        self.new_hosts[host_name].services[
                            service_name].status_information = BeautifulSoup(
                                s['service_output'].replace('\n', ' ').strip(),
                                'html.parser').text
                        self.new_hosts[host_name].services[
                            service_name].passiveonly = not (int(
                                s['service_active_checks_enabled']))
                        self.new_hosts[host_name].services[
                            service_name].notifications_disabled = not (int(
                                s['service_notifications_enabled']))
                        self.new_hosts[host_name].services[
                            service_name].flapping = bool(
                                int(s['service_is_flapping']))
                        self.new_hosts[host_name].services[
                            service_name].acknowledged = bool(
                                int(s['service_acknowledged']))
                        self.new_hosts[host_name].services[
                            service_name].scheduled_downtime = bool(
                                int(s['service_in_downtime']))
                        self.new_hosts[host_name].services[
                            service_name].status_type = status_type

                        # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                        # acknowledge needs service_description and no display name
                        self.new_hosts[host_name].services[
                            service_name].real_name = s['service_description']

                        # extra duration needed for calculation
                        duration = datetime.datetime.now(
                        ) - datetime.datetime.fromtimestamp(
                            int(s['service_last_state_change']))
                        self.new_hosts[host_name].services[
                            service_name].duration = strfdelta(
                                duration,
                                '{days}d {hours}h {minutes}m {seconds}s')

                    del s, host_name, service_name
        except:

            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # some cleanup
        del jsonraw, error, hosts, services

        # dummy return in case all is OK
        return Result()
Esempio n. 17
0
    def _get_status(self):
        """
            Get status from Zabbix Server
        """
        # =========================================
        # problems
        # =========================================
        problems = []
        try:
            #Are we logged in?
            if self.zlapi is None:
                self.zlapi = ZabbixLightApi(server_name=self.name,
                                            monitor_url=self.monitor_url,
                                            validate_certs=self.validate_certs)

            #zabbix could get an upgrade between checks, we need to check version each time
            self.zbx_version = self.zlapi.do_request("apiinfo.version", {},
                                                     no_auth=True)

            #check are we still logged in, if not, relogin
            if not self.zlapi.logged_in():
                self.zlapi.login(self.username, self.password)

            #Get all current problems (trigger based), no need to check acknowledged problems if they are filtered out (load reduce)
            if conf.filter_acknowledged_hosts_services:
                problems = self.zlapi.do_request("problem.get", {
                    'recent': False,
                    'acknowledged': False
                })
            else:
                problems = self.zlapi.do_request("problem.get",
                                                 {'recent': False})

            for problem in problems:

                #get trigger which rose current problem
                trigger = self.zlapi.do_request(
                    "trigger.get", {
                        'triggerids':
                        problem['objectid'],
                        'monitored':
                        True,
                        'active':
                        True,
                        'skipDependent':
                        True,
                        'selectHosts': [
                            'hostid', 'name', 'maintenance_status',
                            'available', 'error', 'errors_from',
                            'ipmi_available', 'ipmi_error', 'ipmi_errors_from',
                            'jmx_available', 'jmx_error', 'jmx_errors_from',
                            'snmp_available', 'snmp_error', 'snmp_errors_from'
                        ],
                        'selectItems': ['key_', 'lastclock']
                    })

                #problems on disabled/maintenance/deleted hosts don't have triggers
                #have to do that because of how zabbix housekeeping service work
                #API reports past problems for hosts that no longer exist
                if not trigger:
                    continue

                service_id = problem['eventid']
                host_id = trigger[0]['hosts'][0]['hostid']

                #new host to report, we only need to do that at first problem for that host
                if host_id not in self.new_hosts:
                    self.new_hosts[host_id] = GenericHost()
                    self.new_hosts[host_id].name = trigger[0]['hosts'][0][
                        'name']

                    #host has active maintenance period
                    if trigger[0]['hosts'][0]['maintenance_status'] == "1":
                        self.new_hosts[host_id].scheduled_downtime = True

                    #old api shows host interfaces status in host object
                    if parse_version(
                            self.zbx_version) < parse_version("5.4.0"):

                        #host not available via agent
                        if trigger[0]['hosts'][0].get('available', '0') == "2":
                            self.new_hosts[host_id].status = "DOWN"
                            self.new_hosts[
                                host_id].status_information = trigger[0][
                                    'hosts'][0]['error']
                            self.new_hosts[
                                host_id].duration = HumanReadableDurationFromTimestamp(
                                    trigger[0]['hosts'][0]['errors_from'])

                        #host not available via ipmi
                        if trigger[0]['hosts'][0].get('ipmi_available',
                                                      '0') == "2":
                            self.new_hosts[host_id].status = "DOWN"
                            self.new_hosts[
                                host_id].status_information = trigger[0][
                                    'hosts'][0]['ipmi_error']
                            self.new_hosts[
                                host_id].duration = HumanReadableDurationFromTimestamp(
                                    trigger[0]['hosts'][0]['ipmi_errors_from'])

                        #host not available via jmx
                        if trigger[0]['hosts'][0].get('jmx_available',
                                                      '0') == "2":
                            self.new_hosts[host_id].status = "DOWN"
                            self.new_hosts[
                                host_id].status_information = trigger[0][
                                    'hosts'][0]['jmx_error']
                            self.new_hosts[
                                host_id].duration = HumanReadableDurationFromTimestamp(
                                    trigger[0]['hosts'][0]['jmx_errors_from'])

                        #host not available via snmp
                        if trigger[0]['hosts'][0].get('snmp_available',
                                                      '0') == "2":
                            self.new_hosts[host_id].status = "DOWN"
                            self.new_hosts[
                                host_id].status_information = trigger[0][
                                    'hosts'][0]['snmp_error']
                            self.new_hosts[
                                host_id].duration = HumanReadableDurationFromTimestamp(
                                    trigger[0]['hosts'][0]['snmp_errors_from'])

                    #new api shows host interfaces status in hostinterfaces object
                    else:

                        #get all host interfaces
                        hostinterfaces = self.zlapi.do_request(
                            "hostinterface.get", {"hostids": host_id})

                        #check them all and mark host as DOWN on first not available interface
                        for hostinterface in hostinterfaces:
                            if hostinterface.get('available', '0') == "2":
                                self.new_hosts[host_id].status = "DOWN"
                                self.new_hosts[
                                    host_id].status_information = hostinterface[
                                        'error']
                                self.new_hosts[
                                    host_id].duration = HumanReadableDurationFromTimestamp(
                                        hostinterface['errors_from'])
                                #we stop checking rest of interfaces
                                break

                #service to report
                self.new_hosts[host_id].services[service_id] = GenericService()
                self.new_hosts[host_id].services[service_id].host = trigger[0][
                    'hosts'][0]['name']
                self.new_hosts[host_id].services[
                    service_id].status = self.statemap.get(
                        problem['severity'], problem['severity'])
                self.new_hosts[host_id].services[
                    service_id].duration = HumanReadableDurationFromTimestamp(
                        problem['clock'])
                self.new_hosts[host_id].services[service_id].name = trigger[0][
                    'items'][0]['key_']
                self.new_hosts[host_id].services[
                    service_id].last_check = time.strftime(
                        "%d/%m/%Y %H:%M:%S",
                        time.localtime(int(
                            trigger[0]['items'][0]['lastclock'])))

                #we add opdata to status information just like in zabbix GUI
                if problem["opdata"] != "":
                    self.new_hosts[host_id].services[
                        service_id].status_information = problem[
                            'name'] + " (" + problem["opdata"] + ")"
                else:
                    self.new_hosts[host_id].services[
                        service_id].status_information = problem['name']

                #service is acknowledged
                if problem['acknowledged'] == "1":
                    self.new_hosts[host_id].services[
                        service_id].acknowledged = True

        except ZabbixLightApiException:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        return Result()
Esempio n. 18
0
    def _get_status(self):
        """
            Get status from SNAG-View 3 Server - only JSON
        """
        # define CGI URLs for hosts and services
        if self.cgiurl_hosts == None:
            # hosts (up, down, unreachable or pending)
            self.cgiurl_hosts = self.monitor_cgi_url + '/rest/private/nagios/host'

        if self.cgiurl_services == None:
            # services (warning, critical, unknown or pending)
            self.cgiurl_services = self.monitor_cgi_url + \
                                   '/rest/private/nagios/service_status/browser'

        self.new_hosts = dict()

        # hosts
        try:
            form_data = dict()
            form_data['acknowledged'] = 1
            form_data['downtime'] = 1
            form_data['inactiveHosts'] = 0
            form_data['disabledNotification'] = 1
            form_data['limit_start'] = 0
            # Get all hosts
            form_data['limit_length'] = 99999

            result = self.FetchURL(self.cgiurl_hosts,
                                   giveback='raw',
                                   cgi_data=form_data)

            # authentication errors get a status code 200 too
            if result.status_code < 400 and \
                    result.result.startswith('<'):
                # in case of auth error reset HTTP session and try again
                self.reset_HTTP()
                result = self.FetchURL(self.cgiurl_hosts,
                                       giveback='raw',
                                       cgi_data=form_data)

                if result.status_code < 400 and \
                        result.result.startswith('<'):
                    self.refresh_authentication = True
                    return Result(result=result.result,
                                  error='Authentication error',
                                  status_code=result.status_code)

            # purify JSON result
            jsonraw = copy.deepcopy(result.result.replace('\n', ''))
            error = copy.deepcopy(result.error)
            status_code = result.status_code

            if error != '' or status_code >= 400:
                return Result(result=jsonraw,
                              error=error,
                              status_code=status_code)

            self.check_for_error(jsonraw, error, status_code)

            hosts = json.loads(jsonraw)

            for host in hosts['data']:
                h = dict(host)

                # Skip if Host is 'Pending'
                if int(h['sv_host__nagios_status__current_state']) == 4:
                    continue

                # Skip if Host has notifications disabled
                if int(h['sv_host__nagios_status__notifications_enabled']
                       ) == 0:
                    continue

                # host
                host_name = h['sv_host__nagios__host_name']

                # If a host does not exist, create its object
                if host_name not in self.new_hosts:
                    self.new_hosts[host_name] = GenericHost()
                    self.new_hosts[host_name].name = host_name
                    self.new_hosts[host_name].svid = h[
                        'sv_host__svobjects____SVID']
                    self.new_hosts[host_name].server = self.name
                    self.new_hosts[host_name].status = self.STATES_MAPPING[
                        'hosts'][int(
                            h['sv_host__nagios_status__current_state'])]
                    self.new_hosts[
                        host_name].last_check = datetime.datetime.fromtimestamp(
                            int(h['sv_host__nagios_status__last_check']))
                    self.new_hosts[host_name].attempt = h[
                        'sv_host__nagios__max_check_attempts']
                    self.new_hosts[host_name].status_information = h[
                        'sv_host__nagios_status__plugin_output']
                    self.new_hosts[host_name].passiveonly = not (int(
                        h['sv_host__nagios_status__checks_enabled']))
                    self.new_hosts[host_name].notifications_disabled = not (
                        int(h['sv_host__nagios_status__notifications_enabled'])
                    )
                    self.new_hosts[host_name].flapping = int(
                        h['sv_host__nagios_status__is_flapping'])
                    self.new_hosts[host_name].acknowledged = int(h[
                        'sv_host__nagios_status__problem_has_been_acknowledged']
                                                                 )
                    self.new_hosts[host_name].scheduled_downtime = int(
                        h['sv_host__nagios_status__scheduled_downtime_depth'])
                    self.new_hosts[host_name].status_type = 'soft' if int(
                        h['sv_host__nagios_status__state_type']
                    ) == 0 else 'hard'

                    # extra duration needed for calculation
                    duration = datetime.datetime.now(
                    ) - datetime.datetime.fromtimestamp(
                        int(h['sv_host__nagios_status__last_state_change']))

                    self.new_hosts[host_name].duration = strfdelta(
                        duration, '{days}d {hours}h {minutes}m {seconds}s')

                del h, host_name
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            form_data = dict()
            form_data['acknowledged'] = 1
            form_data['downtime'] = 1
            form_data['inactiveHosts'] = 0
            form_data['disabledNotification'] = 1
            form_data['softstate'] = 1
            form_data['limit_start'] = 0
            # Get all services
            form_data['limit_length'] = 99999

            result = self.FetchURL(self.cgiurl_services,
                                   giveback='raw',
                                   cgi_data=form_data)

            # purify JSON result
            jsonraw = copy.deepcopy(result.result.replace('\n', ''))
            error = copy.deepcopy(result.error)
            status_code = result.status_code

            if error != '' or status_code >= 400:
                return Result(result=jsonraw,
                              error=error,
                              status_code=status_code)

            self.check_for_error(jsonraw, error, status_code)

            services = json.loads(jsonraw)

            for service in services['data']:
                s = dict(service)

                # Skip if Host or Service is 'Pending'
                if int(s['sv_service_status__nagios_status__current_state']
                       ) == 4 or int(
                           s['sv_host__nagios_status__current_state']) == 4:
                    continue

                # Skip if Host or Service has notifications disabled
                if int(s[
                        'sv_service_status__nagios_status__notifications_enabled']
                       ) == 0 or int(
                           s['sv_host__nagios_status__notifications_enabled']
                       ) == 0:
                    continue

                # host and service
                host_name = s['sv_host__nagios__host_name']
                service_name = s[
                    'sv_service_status__svobjects__rendered_label']

                # If a service does not exist, create its object
                if service_name not in self.new_hosts[host_name].services:
                    self.new_hosts[host_name].services[
                        service_name] = GenericService()
                    self.new_hosts[host_name].services[
                        service_name].host = host_name
                    self.new_hosts[host_name].services[service_name].svid = s[
                        'sv_service_status__svobjects____SVID']
                    self.new_hosts[host_name].services[
                        service_name].name = service_name
                    self.new_hosts[host_name].services[
                        service_name].server = self.name
                    self.new_hosts[host_name].services[
                        service_name].status = self.STATES_MAPPING['services'][
                            int(s[
                                'sv_service_status__nagios_status__current_state']
                                )]
                    self.new_hosts[host_name].services[
                        service_name].last_check = datetime.datetime.fromtimestamp(
                            int(s[
                                'sv_service_status__nagios_status__last_check']
                                ))
                    self.new_hosts[host_name].services[
                        service_name].attempt = s[
                            'sv_service_status__nagios__max_check_attempts']
                    self.new_hosts[host_name].services[
                        service_name].status_information = BeautifulSoup(
                            s['sv_service_status__nagios_status__plugin_output']
                            .replace('\n', ' ').strip(), 'html.parser').text
                    self.new_hosts[host_name].services[
                        service_name].passiveonly = not (int(s[
                            'sv_service_status__nagios_status__checks_enabled']
                                                             ))
                    self.new_hosts[host_name].services[
                        service_name].notifications_disabled = not (int(s[
                            'sv_service_status__nagios_status__notifications_enabled']
                                                                        ))
                    self.new_hosts[host_name].services[
                        service_name].flapping = int(
                            s['sv_service_status__nagios_status__is_flapping'])
                    self.new_hosts[host_name].services[
                        service_name].acknowledged = int(s[
                            'sv_service_status__nagios_status__problem_has_been_acknowledged']
                                                         )
                    self.new_hosts[host_name].services[
                        service_name].scheduled_downtime = int(s[
                            'sv_service_status__nagios_status__scheduled_downtime_depth']
                                                               )
                    self.new_hosts[host_name].services[
                        service_name].status_type = 'soft' if int(
                            s['sv_service_status__nagios_status__state_type']
                        ) == 0 else 'hard'

                    # acknowledge needs service_description and no display name
                    self.new_hosts[host_name].services[
                        service_name].real_name = s[
                            'sv_service_status__nagios__service_description']

                    # extra duration needed for calculation
                    duration = datetime.datetime.now(
                    ) - datetime.datetime.fromtimestamp(
                        int(s[
                            'sv_service_status__nagios_status__last_state_change']
                            ))
                    self.new_hosts[host_name].services[
                        service_name].duration = strfdelta(
                            duration, '{days}d {hours}h {minutes}m {seconds}s')

                del s, host_name, service_name
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        del jsonraw, error, hosts

        # dummy return in case all is OK
        return Result()
Esempio n. 19
0
    def _get_status_HTML(self):
        """
        Get status from Nagios Server - the oldschool CGI HTML way
        """
        # create Nagios items dictionary with to lists for services and hosts
        # every list will contain a dictionary for every failed service/host
        # this dictionary is only temporarily
        # ##global icons
        nagitems = {'services': [], 'hosts': []}

        # new_hosts dictionary
        self.new_hosts = dict()

        # hosts - mostly the down ones
        # unfortunately the hosts status page has a different structure so
        # hosts must be analyzed separately
        try:
            for status_type in 'hard', 'soft':
                result = self.FetchURL(self.cgiurl_hosts[status_type])
                htobj, error, status_code = result.result,\
                                            result.error,\
                                            result.status_code

                # check if any error occured
                errors_occured = self.check_for_error(htobj, error,
                                                      status_code)
                # if there are errors return them
                if errors_occured != False:
                    return (errors_occured)

                # put a copy of a part of htobj into table to be able to delete htobj
                table = htobj('table', {'class': 'status'})[0]

                # do some cleanup
                del result, error

                # access table rows
                # some Icinga versions have a <tbody> tag in cgi output HTML which
                # omits the <tr> tags being found
                if len(table('tbody')) == 0:
                    trs = table('tr', recursive=False)
                else:
                    tbody = table('tbody')[0]
                    trs = tbody('tr', recursive=False)

                # kick out table heads
                trs.pop(0)

                for tr in trs:
                    try:
                        # ignore empty <tr> rows
                        if len(tr('td', recursive=False)) > 1:
                            n = {}
                            # get tds in one tr
                            tds = tr('td', recursive=False)
                            # host
                            try:
                                n['host'] = str(
                                    tds[0].table.tr.td.table.tr.td.a.string)
                            except:
                                n['host'] = str(nagitems[len(nagitems) -
                                                         1]['host'])
                                # status
                            n['status'] = str(tds[1].string)
                            # last_check
                            n['last_check'] = str(tds[2].string)
                            # duration
                            n['duration'] = str(tds[3].string)
                            # division between Nagios and Icinga in real life... where
                            # Nagios has only 5 columns there are 7 in Icinga 1.3...
                            # ... and 6 in Icinga 1.2 :-)
                            if len(tds) < 7:
                                # the old Nagios table
                                # status_information
                                if len(tds[4](text=not_empty)) == 0:
                                    n['status_information'] = ''
                                else:
                                    n['status_information'] = str(
                                        tds[4].string)
                                    # attempts are not shown in case of hosts so it defaults to 'N/A'
                                n['attempt'] = 'N/A'
                            else:
                                # attempts are shown for hosts
                                # to fix http://sourceforge.net/tracker/?func=detail&atid=1101370&aid=3280961&group_id=236865 .attempt needs
                                # to be stripped
                                n['attempt'] = str(tds[4].string).strip()
                                # status_information
                                if len(tds[5](text=not_empty)) == 0:
                                    n['status_information'] = ''
                                else:
                                    n['status_information'] = str(
                                        tds[5].string)

                            # status flags
                            n['passiveonly'] = False
                            n['notifications_disabled'] = False
                            n['flapping'] = False
                            n['acknowledged'] = False
                            n['scheduled_downtime'] = False

                            # map status icons to status flags
                            icons = tds[0].findAll('img')
                            for i in icons:
                                icon = i['src'].split('/')[-1]
                                if icon in self.STATUS_MAPPING:
                                    n[self.STATUS_MAPPING[icon]] = True
                            # cleaning
                            del icons

                            # add dictionary full of information about this host item to nagitems
                            nagitems['hosts'].append(n)
                            # after collection data in nagitems create objects from its informations
                            # host objects contain service objects
                            if not 'host' in self.new_hosts:
                                new_host = n['host']
                                self.new_hosts[new_host] = GenericHost()
                                self.new_hosts[new_host].name = n['host']
                                self.new_hosts[new_host].server = self.name
                                self.new_hosts[new_host].status = n['status']
                                self.new_hosts[new_host].last_check = n[
                                    'last_check']
                                self.new_hosts[new_host].duration = n[
                                    'duration']
                                self.new_hosts[new_host].attempt = n['attempt']
                                self.new_hosts[
                                    new_host].status_information = n[
                                        'status_information'].replace(
                                            '\n', ' ').strip()
                                self.new_hosts[new_host].passiveonly = n[
                                    'passiveonly']
                                self.new_hosts[
                                    new_host].notifications_disabled = n[
                                        'notifications_disabled']
                                self.new_hosts[new_host].flapping = n[
                                    'flapping']
                                self.new_hosts[new_host].acknowledged = n[
                                    'acknowledged']
                                self.new_hosts[
                                    new_host].scheduled_downtime = n[
                                        'scheduled_downtime']
                                self.new_hosts[
                                    new_host].status_type = status_type

                                # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                                # acknowledge needs host_name and no display name
                                self.new_hosts[new_host].real_name = n['host']

                            # some cleanup
                            del tds, n
                    except:
                        self.Error(sys.exc_info())

                # do some cleanup
                htobj.decompose()
                del htobj, trs, table

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            for status_type in 'hard', 'soft':
                result = self.FetchURL(self.cgiurl_services[status_type])
                htobj, error, status_code = result.result,\
                                            result.error,\
                                            result.status_code

                # check if any error occured
                errors_occured = self.check_for_error(htobj, error,
                                                      status_code)
                # if there are errors return them
                if errors_occured != False:
                    return (errors_occured)

                table = htobj('table', {'class': 'status'})[0]

                # some Icinga versions have a <tbody> tag in cgi output HTML which
                # omits the <tr> tags being found
                if len(table('tbody')) == 0:
                    trs = table('tr', recursive=False)
                else:
                    tbody = table('tbody')[0]
                    trs = tbody('tr', recursive=False)

                # do some cleanup
                del result, error

                # kick out table heads
                trs.pop(0)

                for tr in trs:
                    try:
                        # ignore empty <tr> rows - there are a lot of them - a Nagios bug?
                        tds = tr('td', recursive=False)
                        if len(tds) > 1:
                            n = {}
                            # host
                            # the resulting table of Nagios status.cgi table omits the
                            # hostname of a failing service if there are more than one
                            # so if the hostname is empty the nagios status item should get
                            # its hostname from the previuos item - one reason to keep 'nagitems'
                            try:
                                n['host'] = str(tds[0](text=not_empty)[0])
                            except:
                                n['host'] = str(nagitems['services'][
                                    len(nagitems['services']) - 1]['host'])
                                # service
                            n['service'] = str(tds[1](text=not_empty)[0])
                            # status
                            n['status'] = str(tds[2](text=not_empty)[0])
                            # last_check
                            n['last_check'] = str(tds[3](text=not_empty)[0])
                            # duration
                            n['duration'] = str(tds[4](text=not_empty)[0])
                            # attempt
                            # to fix http://sourceforge.net/tracker/?func=detail&atid=1101370&aid=3280961&group_id=236865 .attempt needs
                            # to be stripped
                            n['attempt'] = str(
                                tds[5](text=not_empty)[0]).strip()
                            # status_information
                            if len(tds[6](text=not_empty)) == 0:
                                n['status_information'] = ''
                            else:
                                n['status_information'] = str(
                                    tds[6](text=not_empty)[0])
                                # status flags
                            n['passiveonly'] = False
                            n['notifications_disabled'] = False
                            n['flapping'] = False
                            n['acknowledged'] = False
                            n['scheduled_downtime'] = False

                            # map status icons to status flags
                            icons = tds[1].findAll('img')
                            for i in icons:
                                icon = i['src'].split('/')[-1]
                                if icon in self.STATUS_MAPPING:
                                    n[self.STATUS_MAPPING[icon]] = True
                            # cleaning
                            del icons

                            # add dictionary full of information about this service item to nagitems - only if service
                            nagitems['services'].append(n)
                            # after collection data in nagitems create objects of its informations
                            # host objects contain service objects
                            if not n['host'] in self.new_hosts:
                                self.new_hosts[n['host']] = GenericHost()
                                self.new_hosts[n['host']].name = n['host']
                                self.new_hosts[n['host']].status = 'UP'
                                # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                                # acknowledge needs host_description and no display name
                                self.new_hosts[n['host']].real_name = n['host']

                                # trying to fix https://sourceforge.net/tracker/index.php?func=detail&aid=3299790&group_id=236865&atid=1101370
                                # if host is not down but in downtime or any other flag this should be evaluated too
                                # map status icons to status flags
                                icons = tds[0].findAll('img')
                                for i in icons:
                                    icon = i['src'].split('/')[-1]
                                    if icon in self.STATUS_MAPPING:
                                        self.new_hosts[n['host']].__dict__[
                                            self.STATUS_MAPPING[icon]] = True
                                # cleaning
                                del icons
                                # if a service does not exist create its object
                            if not n['service'] in self.new_hosts[
                                    n['host']].services:
                                new_service = n['service']
                                self.new_hosts[n['host']].services[
                                    new_service] = GenericService()
                                self.new_hosts[n['host']].services[
                                    new_service].host = n['host']
                                self.new_hosts[n['host']].services[
                                    new_service].server = self.name
                                self.new_hosts[n['host']].services[
                                    new_service].name = n['service']
                                self.new_hosts[n['host']].services[
                                    new_service].status = n['status']
                                self.new_hosts[n['host']].services[
                                    new_service].last_check = n['last_check']
                                self.new_hosts[n['host']].services[
                                    new_service].duration = n['duration']
                                self.new_hosts[n['host']].services[
                                    new_service].attempt = n['attempt']
                                self.new_hosts[n['host']].services[
                                    new_service].status_information = n[
                                        'status_information'].replace(
                                            '\n', ' ').strip()
                                self.new_hosts[n['host']].services[
                                    new_service].passiveonly = n['passiveonly']
                                self.new_hosts[n['host']].services[
                                    new_service].notifications_disabled = n[
                                        'notifications_disabled']
                                self.new_hosts[n['host']].services[
                                    new_service].flapping = n['flapping']
                                self.new_hosts[n['host']].services[
                                    new_service].acknowledged = n[
                                        'acknowledged']
                                self.new_hosts[n['host']].services[
                                    new_service].scheduled_downtime = n[
                                        'scheduled_downtime']

                                # extra Icinga properties to solve https://github.com/HenriWahl/Nagstamon/issues/192
                                # acknowledge needs service_description and no display name
                                self.new_hosts[n['host']].services[
                                    new_service].real_name = n[
                                        'service_description']

                            # some cleanup
                            del tds, n
                    except:
                        self.Error(sys.exc_info())

                # do some cleanup
                htobj.decompose()
                del htobj, trs, table

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

            # some cleanup
        del nagitems

        # dummy return in case all is OK
        return Result()
Esempio n. 20
0
    def _get_status(self):
        nagitems = {"services":[], "hosts":[]}

        self.new_hosts = dict()

        try:
            hosts = self._get_all_events()
            
            if 'events' in hosts:
                hosts = hosts['events']

                for host in hosts:
                    n = dict()
                    n['evid'] = host['evid']
                    n['host'] = host['device']['text']
                    n['service'] = host['eventClass']['text']

                    n['status'] = self.SEVERITY_MAP.get(host['severity'])
                    n['last_check'] = host['lastTime']
                
                    duration = self._calc_duration(host['firstTime'], host['lastTime'])
                    if (duration == None):
                        continue #Zenoss needs a length to cause an error
                    n['duration'] = duration

                    n["status_information"] = host['message']
                    n["attempt"] = str(host['count'])+"/1" # needs a / with a number on either side to work

                    n["passiveonly"] = False
                    n["notifications_disabled"] = False
                    n["flapping"] = False
                    n["acknowledged"] = (host['eventState'] == 'Acknowledged')
                    n["scheduled_downtime"] = False
              
                    nagitems["hosts"].append(n)

                    new_host = n["host"]
                    if not new_host in self.new_hosts:
                        self.new_hosts[new_host] = GenericHost()
                        self.new_hosts[new_host].name = new_host
                    
                    if not new_host in self.new_hosts[new_host].services:
                        
                        new_service = new_host
                        self.new_hosts[new_host].services[new_service] = GenericService()
                        
                        self.new_hosts[new_host].services[new_service].host = new_host
                        self.new_hosts[new_host].services[new_service].evid = n['evid']
                        self.new_hosts[new_host].services[new_service].name = n["service"]
                    
                        self.new_hosts[new_host].services[new_service].server = self.name
                        self.new_hosts[new_host].services[new_service].status = n["status"]
                        self.new_hosts[new_host].services[new_service].last_check = n["last_check"]
                    
                        self.new_hosts[new_host].services[new_service].duration = n["duration"]
                        self.new_hosts[new_host].services[new_service].status_information= n["status_information"].encode("utf-8")
                        self.new_hosts[new_host].services[new_service].attempt = n["attempt"]

                        self.new_hosts[new_host].services[new_service].passiveonly = n["passiveonly"]
                        self.new_hosts[new_host].services[new_service].notifications_disabled = n["notifications_disabled"]
                        self.new_hosts[new_host].services[new_service].flapping = n["flapping"]
                        self.new_hosts[new_host].services[new_service].acknowledged = n["acknowledged"]
                        self.new_hosts[new_host].services[new_service].scheduled_downtime = n["scheduled_downtime"]
                    del n
                
        except:
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(traceback.format_exc())
            return Result(result=result, error=error)

        
        del nagitems
        return Result(error="")
Esempio n. 21
0
    def _get_status(self):
        """
        Get status from Prometheus Server
        """
        # get all alerts from the API server
        try:
            result = self.FetchURL(self.monitor_url + self.API_PATH_ALERTS,
                                   giveback="raw")
            data = json.loads(result.result)
            error = result.error
            status_code = result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            if errors_occured is not False:
                return (errors_occured)

            if conf.debug_mode:
                self.Debug(server=self.get_name(),
                           debug="Fetched JSON: " + pprint.pformat(data))

            for alert in data["data"]["alerts"]:
                if conf.debug_mode:
                    self.Debug(server=self.get_name(),
                               debug="Processing Alert: " +
                               pprint.pformat(alert))

                labels = alert.get("labels", {})

                # skip alerts with none severity
                severity = labels.get("severity", "UNKNOWN").upper()
                if severity == "NONE":
                    continue

                hostname = "unknown"
                for host_label in self.map_to_hostname.split(','):
                    if host_label in labels:
                        hostname = labels.get(host_label)
                        break

                servicename = "unknown"
                for service_label in self.map_to_servicename.split(','):
                    if service_label in labels:
                        servicename = labels.get(service_label)
                        break

                service = PrometheusService()
                service.host = str(hostname)
                service.name = servicename
                service.server = self.name
                service.status = severity
                service.last_check = "n/a"
                service.attempt = alert.get("state", "firirng")
                service.duration = str(self._get_duration(alert["activeAt"]))

                annotations = alert.get("annotations", {})
                status_information = ""
                for status_information_label in self.map_to_status_information.split(
                        ','):
                    if status_information_label in annotations:
                        status_information = annotations.get(
                            status_information_label)
                        break
                service.status_information = status_information

                if hostname not in self.new_hosts:
                    self.new_hosts[hostname] = GenericHost()
                    self.new_hosts[hostname].name = str(hostname)
                    self.new_hosts[hostname].server = self.name
                self.new_hosts[hostname].services[servicename] = service

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # dummy return in case all is OK
        return Result()
Esempio n. 22
0
    def _get_status(self):
        """
	        Get status from Opsview Server
        """
        # following XXXX to get ALL services in ALL states except OK
        # because we filter them out later
        # the REST API gets all host and service info in one call
        try:
            result = self.FetchURL(
                self.monitor_url +
                "/rest/status/service?state=1&state=2&state=3",
                giveback="raw")
            data, error, status_code = json.loads(
                result.result), result.error, result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            # if there are errors return them
            if errors_occured != False:
                return (errors_occured)

            if conf.debug_mode:
                self.Debug(server=self.get_name(),
                           debug="Fetched JSON: " + pprint.pformat(data))

            for host in data["list"]:
                self.new_hosts[host["name"]] = GenericHost()
                self.new_hosts[host["name"]].name = str(host["name"])
                self.new_hosts[host["name"]].server = self.name
                # states come in lower case from Opsview
                self.new_hosts[host["name"]].status = str(
                    host["state"].upper())
                self.new_hosts[host["name"]].status_type = str(
                    host["state_type"])
                self.new_hosts[
                    host["name"]].last_check = datetime.fromtimestamp(
                        int(host["last_check"])).strftime(
                            "%Y-%m-%d %H:%M:%S %z")
                self.new_hosts[
                    host["name"]].duration = HumanReadableDurationFromSeconds(
                        host["state_duration"])
                self.new_hosts[host["name"]].attempt = host[
                    "current_check_attempt"] + "/" + host["max_check_attempts"]
                self.new_hosts[
                    host["name"]].status_information = host["output"].replace(
                        "\n", " ")

                # if host is in downtime add it to known maintained hosts
                if host['downtime'] != "0":
                    self.new_hosts[host["name"]].scheduled_downtime = True
                #if host.has_key("acknowledged"):
                if 'acknowledged' in host:
                    self.new_hosts[host["name"]].acknowledged = True
                #if host.has_key("flapping"):
                if 'flapping' in host:
                    self.new_hosts[host["name"]].flapping = True

                #services
                for service in host["services"]:
                    self.new_hosts[host["name"]].services[
                        service["name"]] = OpsviewService()
                    self.new_hosts[host["name"]].services[
                        service["name"]].host = str(host["name"])
                    self.new_hosts[host["name"]].services[
                        service["name"]].name = service["name"]
                    self.new_hosts[host["name"]].services[
                        service["name"]].server = self.name

                    # states come in lower case from Opsview
                    self.new_hosts[host["name"]].services[
                        service["name"]].status = service["state"].upper()
                    self.new_hosts[host["name"]].services[
                        service["name"]].status_type = service["state_type"]
                    self.new_hosts[host["name"]].services[
                        service["name"]].last_check = datetime.fromtimestamp(
                            int(service["last_check"])).strftime(
                                "%Y-%m-%d %H:%M:%S %z")
                    self.new_hosts[host["name"]].services[service[
                        "name"]].duration = HumanReadableDurationFromSeconds(
                            service["state_duration"])
                    self.new_hosts[host["name"]].services[
                        service["name"]].attempt = service[
                            "current_check_attempt"] + "/" + service[
                                "max_check_attempts"]
                    self.new_hosts[host["name"]].services[
                        service["name"]].status_information = service[
                            "output"].replace("\n", " ")
                    if service['downtime'] != '0':
                        self.new_hosts[host["name"]].services[
                            service["name"]].scheduled_downtime = True
                    #if service.has_key("acknowledged"):
                    if 'acknowledged' in service:
                        self.new_hosts[host["name"]].services[
                            service["name"]].acknowledged = True
                    #f service.has_key("flapping"):
                    if 'flapping' in service:
                        self.new_hosts[host["name"]].services[
                            service["name"]].flapping = True
                    # extra opsview id for service, needed for submitting check results
                    self.new_hosts[host["name"]].services[
                        service["name"]].service_object_id = service[
                            "service_object_id"]

        except:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        #dummy return in case all is OK
        return Result()
Esempio n. 23
0
    def _get_status(self):
        """
            Get status from Icinga Server and translate it into Nagstamon magic
            generic array
        """
        # new_hosts dictionary
        self.new_hosts = dict()

        # hosts - the down ones
        try:
            # We ask icinga for hosts which are not doing well
            hosts = self._get_host_events()
            for host in hosts:
                host_name = host['attrs']['name']
                if host_name not in self.new_hosts:
                    self.new_hosts[host_name] = GenericHost()
                    self.new_hosts[host_name].name = host_name
                    self.new_hosts[host_name].site = self.name
                    try:
                        self.new_hosts[
                            host_name].status = self.HOST_SEVERITY_CODE_TEXT_MAP.get(
                                host['attrs']['state'])
                    except KeyError:
                        self.new_hosts[host_name].status = 'UNKNOWN'
                    if int(
                            host['attrs']['state_type']
                    ) > 0:  # if state is not SOFT, icinga does not report attempts properly
                        self.new_hosts[host_name].attempt = "{}/{}".format(
                            int(host['attrs']['max_check_attempts']),
                            int(host['attrs']['max_check_attempts']))
                    else:
                        self.new_hosts[host_name].attempt = "{}/{}".format(
                            int(host['attrs']['check_attempt']),
                            int(host['attrs']['max_check_attempts']))
                    self.new_hosts[host_name].last_check = arrow.get(
                        host['attrs']['last_check']).humanize()
                    self.new_hosts[host_name].duration = arrow.get(
                        host['attrs']['previous_state_change']).humanize()
                    self.new_hosts[host_name].status_information = host[
                        'attrs']['last_check_result']['output']
                    self.new_hosts[host_name].passiveonly = not (
                        host['attrs']['enable_active_checks'])
                    self.new_hosts[host_name].notifications_disabled = not (
                        host['attrs']['enable_notifications'])
                    self.new_hosts[host_name].flapping = host['attrs'][
                        'flapping']
                    self.new_hosts[host_name].acknowledged = host['attrs'][
                        'acknowledgement']
                    self.new_hosts[host_name].status_type = {
                        0: "soft",
                        1: "hard"
                    }[host['attrs']['state_type']]
                del host_name
            del hosts

        except Exception as e:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            log.exception(e)
            return Result(result=result, error=error)

        # services
        try:
            services = self._get_service_events()
            for service in services:
                new_service = GenericService()
                new_service.host = service['attrs']['host_name']
                new_service.name = service['attrs']['name']
                try:
                    new_service.status = self.SERVICE_SEVERITY_CODE_TEXT_MAP.get(
                        service['attrs']['state'])
                except KeyError:
                    new_service.status = 'UNKNOWN'
                if int(
                        service['attrs']['state_type']
                ) > 0:  # if state is not SOFT, icinga does not report attempts properly
                    new_service.attempt = "{}/{}".format(
                        int(service['attrs']['max_check_attempts']),
                        int(service['attrs']['max_check_attempts']))
                else:
                    new_service.attempt = "{}/{}".format(
                        int(service['attrs']['check_attempt']),
                        int(service['attrs']['max_check_attempts']))
                new_service.last_check = arrow.get(
                    service['attrs']['last_check']).humanize()
                new_service.duration = arrow.get(
                    service['attrs']['previous_state_change']).humanize()
                new_service.status_information = service['attrs'][
                    'last_check_result']['output']
                new_service.passiveonly = not (
                    service['attrs']['enable_active_checks'])
                new_service.notifications_disabled = not (
                    service['attrs']['enable_notifications'])
                new_service.flapping = service['attrs']['flapping']
                new_service.acknowledged = service['attrs']['acknowledgement']
                new_service.status_type = {
                    0: "soft",
                    1: "hard"
                }[service['attrs']['state_type']]
                self._insert_service_to_hosts(new_service)
            del services

        except Exception as e:
            log.exception(e)
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # dummy return in case all is OK
        return Result()
Esempio n. 24
0
    def _get_status(self):
        """
            Get status from monitos 4 Server - only JSON
        """
        # define CGI URLs for hosts and services

        if self.use_autologin is True:
            if self.cgiurl_hosts is None:
                # hosts (up, down, unreachable)
                self.cgiurl_hosts = self.monitor_cgi_url + '/api/host?include=status,configuration&limit=100&filter[states]=0,1,2&filter[onlysyncenabled]' + '&authtoken=' + self.autologin_key

            if self.cgiurl_services is None:
                # services (warning, critical, unknown)
                self.cgiurl_services = self.monitor_cgi_url + \
                                       '/api/serviceinstance?include=status,configuration&limit=100&filter[states]=1,2,3&filter[onlysyncenabled]' + '&authtoken=' + self.autologin_key
        else:
            if self.cgiurl_hosts is None:
                # hosts (up, down, unreachable)
                self.cgiurl_hosts = self.monitor_cgi_url + '/api/host?include=status,configuration&limit=100&filter[states]=0,1,2&filter[onlysyncenabled]'

            if self.cgiurl_services is None:
                # services (warning, critical, unknown)
                self.cgiurl_services = self.monitor_cgi_url + '/api/serviceinstance?include=status,configuration&limit=100&filter[states]=1,2,3&filter[onlysyncenabled]'

        self.new_hosts = dict()

        # hosts
        try:
            form_data = dict()

            page = 1

            # loop trough all api pages
            while True:
                cgiurl_hosts_page = self.cgiurl_hosts + '&page=' + str(page)

                result = self.FetchURL(cgiurl_hosts_page,
                                       giveback='raw',
                                       cgi_data=None)

                # authentication errors get a status code 200 too
                if result.status_code < 400 and \
                        result.result.startswith('<'):
                    # in case of auth error reset HTTP session and try again
                    self.reset_HTTP()
                    result = self.FetchURL(cgiurl_hosts_page,
                                           giveback='raw',
                                           cgi_data=None)

                    if result.status_code < 400 and \
                            result.result.startswith('<'):
                        self.refresh_authentication = True
                        return Result(result=result.result,
                                      error='Authentication error',
                                      status_code=result.status_code)

                # purify JSON result
                jsonraw = copy.deepcopy(result.result.replace('\n', ''))
                error = copy.deepcopy(result.error)
                status_code = result.status_code

                if error != '' or status_code >= 400:
                    return Result(result=jsonraw,
                                  error=error,
                                  status_code=status_code)

                self.check_for_error(jsonraw, error, status_code)

                hosts = json.loads(jsonraw)
                if not hosts['data']:
                    break

                page += 1

                for host in hosts['data']:
                    h = dict(host)

                    # Skip if host is disabled
                    if h['syncEnabled'] is not None:
                        if not int(h['syncEnabled']):
                            continue

                    # host
                    host_name = h['name']

                    if conf.debug_mode:
                        self.Debug(server=self.get_name(),
                                   debug=time.strftime('%a %H:%M:%S') +
                                   ' host_name is: ' + host_name)

                    # If a host does not exist, create its object
                    if host_name not in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].uuid = h['uuid']
                        self.new_hosts[host_name].server = 'monitos'

                        try:
                            self.new_hosts[
                                host_name].status = self.STATES_MAPPING[
                                    'hosts'][int(h['status']['currentState'])]
                        except:
                            pass

                        try:
                            self.new_hosts[
                                host_name].last_check = datetime.datetime.fromtimestamp(
                                    int(h['status']['lastCheck']))
                        except:
                            pass

                        self.new_hosts[host_name].attempt = h['configuration'][
                            'maxCheckAttempts']

                        try:
                            self.new_hosts[
                                host_name].status_information = BeautifulSoup(
                                    h['status']['output'].replace('\n',
                                                                  ' ').strip(),
                                    'html.parser').text
                        except:
                            self.new_hosts[host_name].services[
                                service_name].status_information = 'Cant parse output'

                        self.new_hosts[host_name].passiveonly = not (int(
                            h['status']['checksEnabled']))

                        try:
                            self.new_hosts[
                                host_name].notifications_disabled = not (int(
                                    s['status']['notificationsEnabled']))
                        except:
                            self.new_hosts[
                                host_name].notifications_disabled = False

                        try:
                            self.new_hosts[host_name].flapping = (int(
                                h['status']['isFlapping']))
                        except:
                            self.new_hosts[host_name].flapping = False

                        if h['status']['acknowleged'] is None:
                            self.new_hosts[host_name].acknowledged = False
                        else:
                            if h['status']['acknowleged'] != 0:
                                self.new_hosts[host_name].acknowledged = True

                        try:
                            if int(h['status']['scheduledDowntimeDepth']) != 0:
                                self.new_hosts[
                                    host_name].scheduled_downtime = True
                        except:
                            self.new_hosts[
                                host_name].scheduled_downtime = False

                        try:
                            self.new_hosts[
                                host_name].status_type = 'soft' if int(
                                    h['status']['stateType']) == 0 else 'hard'
                        except:
                            self.new_hosts[host_name].status_type = 'hard'

                        # extra duration needed for calculation
                        if h['status']['lastStateChange'] is None:
                            self.Debug(
                                server=self.get_name(),
                                debug=time.strftime('%a %H:%M:%S') +
                                'Host has wrong lastStateChange - host_name is: '
                                + host_name)
                        else:
                            duration = datetime.datetime.now(
                            ) - datetime.datetime.fromtimestamp(
                                int(h['status']['lastStateChange']))
                            self.new_hosts[host_name].duration = strfdelta(
                                duration,
                                '{days}d {hours}h {minutes}m {seconds}s')

                    del h, host_name
                del hosts
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # services
        try:
            form_data = dict()

            page = 1

            # loop trough all api pages
            while True:
                cgiurl_services_page = self.cgiurl_services + '&page=' + str(
                    page)

                result = self.FetchURL(cgiurl_services_page,
                                       giveback='raw',
                                       cgi_data=None)

                # purify JSON result
                jsonraw = copy.deepcopy(result.result.replace('\n', ''))
                error = copy.deepcopy(result.error)
                status_code = result.status_code

                if error != '' or status_code >= 400:
                    return Result(result=jsonraw,
                                  error=error,
                                  status_code=status_code)

                self.check_for_error(jsonraw, error, status_code)

                services = json.loads(jsonraw)
                if not services['data']:
                    break

                page += 1

                for service in services['data']:
                    s = dict(service)

                    # Skip if host is disabled
                    if s['syncEnabled'] is not None:
                        if not int(s['syncEnabled']):
                            continue

                    # host and service
                    host_name = s['configuration']['hostName']
                    service_name = s['configuration']['serviceDescription']

                    if conf.debug_mode:
                        self.Debug(server=self.get_name(),
                                   debug=time.strftime('%a %H:%M:%S') +
                                   ' host_name is: ' + host_name +
                                   ' service_name is: ' + service_name)

                    # If host not in problem list, create it
                    if host_name not in self.new_hosts:
                        self.new_hosts[host_name] = GenericHost()
                        self.new_hosts[host_name].name = host_name
                        self.new_hosts[host_name].uuid = s['configuration'][
                            'host']['uuid']
                        self.new_hosts[host_name].status = self.STATES_MAPPING[
                            'services'][0]

                    # If a service does not exist, create its object
                    if service_name not in self.new_hosts[host_name].services:
                        self.new_hosts[host_name].services[
                            service_name] = GenericService()
                        self.new_hosts[host_name].services[
                            service_name].host = s['configuration']['hostName']
                        self.new_hosts[host_name].services[
                            service_name].uuid = s['uuid']
                        self.new_hosts[host_name].services[
                            service_name].name = service_name
                        self.new_hosts[host_name].services[
                            service_name].server = 'monitos'

                        try:
                            self.new_hosts[host_name].services[
                                service_name].status = self.STATES_MAPPING[
                                    'services'][int(
                                        s['status']['currentState'])]
                        except:
                            pass

                        try:
                            self.new_hosts[host_name].services[
                                service_name].last_check = datetime.datetime.fromtimestamp(
                                    int(s['status']['lastCheck']))
                        except:
                            pass

                        self.new_hosts[host_name].services[
                            service_name].attempt = s['configuration'][
                                'maxCheckAttempts']

                        try:
                            self.new_hosts[host_name].services[
                                service_name].status_information = BeautifulSoup(
                                    s['status']['output'].replace('\n',
                                                                  ' ').strip(),
                                    'html.parser').text
                        except:
                            self.new_hosts[host_name].services[
                                service_name].status_information = 'Cant parse output'

                        self.new_hosts[host_name].services[
                            service_name].passiveonly = not (int(
                                s['status']['checksEnabled']))

                        try:
                            self.new_hosts[host_name].services[
                                service_name].notifications_disabled = not (
                                    int(s['status']['notificationsEnabled']))
                        except:
                            self.new_hosts[host_name].services[
                                service_name].notifications_disabled = False

                        try:
                            self.new_hosts[host_name].services[
                                service_name].flapping = (int(
                                    s['status']['isFlapping']))
                        except:
                            self.new_hosts[host_name].services[
                                service_name].flapping = False

                        if s['status']['acknowleged'] is None:
                            self.new_hosts[host_name].services[
                                service_name].acknowledged = False
                        else:
                            if s['status']['acknowleged'] != 0:
                                self.new_hosts[host_name].services[
                                    service_name].acknowledged = True

                        try:
                            if int(s['status']['scheduledDowntimeDepth']) != 0:
                                self.new_hosts[host_name].services[
                                    service_name].scheduled_downtime = True
                        except:
                            self.new_hosts[host_name].services[
                                service_name].scheduled_downtime = False

                        try:
                            self.new_hosts[host_name].services[
                                service_name].status_type = 'soft' if int(
                                    s['status']['stateType']) == 0 else 'hard'
                        except:
                            self.new_hosts[host_name].services[
                                service_name].status_type = 'hard'

                        # extra duration needed for calculation
                        if s['status']['lastStateChange'] is None:
                            self.Debug(
                                server=self.get_name(),
                                debug=time.strftime('%a %H:%M:%S') +
                                'Service has wrong lastStateChange - host_name is '
                                + host_name + ' service_name is: ' +
                                service_name)
                        else:
                            duration = datetime.datetime.now(
                            ) - datetime.datetime.fromtimestamp(
                                int(s['status']['lastStateChange']))
                            self.new_hosts[host_name].services[
                                service_name].duration = strfdelta(
                                    duration,
                                    '{days}d {hours}h {minutes}m {seconds}s')

                    del s, host_name, service_name
                del services
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        del jsonraw, error, hosts

        # dummy return in case all is OK
        return Result()
Esempio n. 25
0
    def _get_status(self):
        """
        Get status from Alertmanager Server
        """

        log.debug("detection config (map_to_status_information): '%s'",
                  self.map_to_status_information)
        log.debug("detection config (map_to_hostname): '%s'",
                  self.map_to_hostname)
        log.debug("detection config (map_to_servicename): '%s'",
                  self.map_to_servicename)
        log.debug("detection config (alertmanager_filter): '%s'",
                  self.alertmanager_filter)

        # get all alerts from the API server
        try:
            if self.alertmanager_filter != '':
                result = self.FetchURL(
                    self.monitor_url + self.API_PATH_ALERTS +
                    self.API_FILTERS + self.alertmanager_filter,
                    giveback="raw")
            else:
                result = self.FetchURL(self.monitor_url + self.API_PATH_ALERTS,
                                       giveback="raw")

            if result.status_code == 200:
                log.debug(
                    "received status code '%s' with this content in result.result: \n\
-----------------------------------------------------------------------------------------------------------------------------\n\
%s\
-----------------------------------------------------------------------------------------------------------------------------",
                    result.status_code, result.result)
            else:
                log.error("received status code '%s'", result.status_code)

            data = json.loads(result.result)
            error = result.error
            status_code = result.status_code

            # check if any error occured
            errors_occured = self.check_for_error(data, error, status_code)
            if errors_occured is not False:
                return (errors_occured)

            for alert in data:
                alert_data = self._process_alert(alert)
                if not alert_data:
                    break

                service = PrometheusService()
                service.host = alert_data['host']
                service.name = alert_data['name']
                service.server = alert_data['server']
                service.status = alert_data['status']
                service.labels = alert_data['labels']
                service.scheduled_downtime = alert_data['scheduled_downtime']
                service.acknowledged = alert_data['acknowledged']
                service.last_check = alert_data['last_check']
                service.attempt = alert_data['attempt']
                service.duration = alert_data['duration']

                service.generatorURL = alert_data['generatorURL']
                service.fingerprint = alert_data['fingerprint']

                service.status_information = alert_data['status_information']

                if service.host not in self.new_hosts:
                    self.new_hosts[service.host] = GenericHost()
                    self.new_hosts[service.host].name = str(service.host)
                    self.new_hosts[service.host].server = self.name
                self.new_hosts[service.host].services[service.name] = service

        except Exception as e:
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            log.exception(e)
            return Result(result=result, error=error)

        # dummy return in case all is OK
        return Result()
Esempio n. 26
0
    def _get_status(self):
        """
            Get status from Zabbix Server
        """
        ret = Result()
        # create Nagios items dictionary with to lists for services and hosts
        # every list will contain a dictionary for every failed service/host
        # this dictionary is only temporarily
        nagitems = {"services": [], "hosts": []}

        # Create URLs for the configured filters
        if self.zapi is None:
            self._login()

        try:
            # =========================================
            # Hosts Zabbix API data
            # =========================================
            hosts = []
            try:
                hosts = self.zapi.host.get({"output": ["hostid", "host", "name", "status", \
                                                       "available",      "error",      "errors_from", \
                                                       "snmp_available", "snmp_error", "snmp_errors_from", \
                                                       "ipmi_available", "ipmi_error", "ipmi_errors_from", \
                                                       "jmx_available",  "jmx_error",  "jmx_errors_from", \
                                                       "maintenance_status", "maintenance_from"], "selectInterfaces": ["ip"], "filter": {}})
            except (ZabbixError, ZabbixAPIException, APITimeout, Already_Exists):
                # set checking flag back to False
                self.isChecking = False
                result, error = self.Error(sys.exc_info())
                return Result(result=result, error=error)

            # get All Hosts.
            # 1. Store data in cache (to be used by events)
            # 2. We store as faulty two kinds of hosts incidences:
            #    - Disabled hosts
            #    - Hosts with issues trying to connect to agent/service
            #    - In maintenance
            # status = 1 -> Disabled
            # available ZBX: 0 -> No agents 1 -> available 2-> Agent access error
            # ipmi_available IPMI: 0 -> No agents 1 -> available 2-> Agent access error
            # maintenance_status = 1 In maintenance
            for host in hosts:
                
                n = {
                    'host': host['host'],
                    'name': host['name'],
                    'server': self.name,
                    'status': 'UP', # Host is OK by default
                    'last_check': 'n/a',
                    'duration': '',
                    'attempt': 'N/A',
                    'status_information': '',
                    # status flags
                    'passiveonly': False,
                    'notifications_disabled': False,
                    'flapping': False,
                    'acknowledged': False,
                    'scheduled_downtime': False,
                    # Zabbix backend data
                    'hostid': host['hostid'],
                    'site': '',
                    'address': host['interfaces'][0]['ip'],
                }


                if host['maintenance_status'] == '1':
                    n['scheduled_downtime'] = True

                if host['status'] == '1':
                    # filter services and hosts by "filter_hosts_services_disabled_notifications"
                    n['notifications_disabled'] = True
                    # Filter only hosts by filter "Host & services with disabled checks"
                    n['passiveonly']           = True
                # attempt to fix https://github.com/HenriWahl/Nagstamon/issues/535
                # if host['available'] == '0' and host['snmp_available'] == '0' and host['ipmi_available'] == '0' and host['jmx_available'] == '0':
                #     n['status']             = 'UNREACHABLE'
                #     n['status_information'] = 'Host agents in unknown state'
                #     n['duration']           = 'Unknown'
                if host['ipmi_available'] == '2':
                    n['status']             = 'DOWN'
                    n['status_information'] = host['ipmi_error']
                    n['duration']           = HumanReadableDurationFromTimestamp(host['ipmi_errors_from'])
                if host['snmp_available'] == '2':
                    n['status']             = 'DOWN'
                    n['status_information'] = host['snmp_error']
                    n['duration']           = HumanReadableDurationFromTimestamp(host['snmp_errors_from'])
                if host['jmx_available'] == '2':
                    n['status']             = 'DOWN'
                    n['status_information'] = host['jmx_error']
                    n['duration']           = HumanReadableDurationFromTimestamp(host['jmx_errors_from'])
                if host['available'] == '2':
                    n['status']             = 'DOWN'
                    n['status_information'] = host['error']
                    n['duration']           = HumanReadableDurationFromTimestamp(host['errors_from'])
                
                # Zabbix shows OK hosts too - kick 'em!
                if not n['status'] == 'UP':
                    # add dictionary full of information about this host item to nagitems
                    nagitems["hosts"].append(n)

                # after collection data in nagitems create objects from its informations
                # host objects contain service objects
                #key_host = n["host"]
                key_host = n["name"] if len(n['name']) != 0 else n["host"];

                #key_host = n["hostid"]
                if key_host not in self.new_hosts:
                    self.new_hosts[key_host] = GenericHost()
                    self.new_hosts[key_host].hostid = n["hostid"]
                    self.new_hosts[key_host].host = n["host"]
                    self.new_hosts[key_host].name = n["name"]
                    self.new_hosts[key_host].status = n["status"]
                    self.new_hosts[key_host].last_check = n["last_check"]
                    self.new_hosts[key_host].duration = n["duration"]
                    self.new_hosts[key_host].attempt = n["attempt"]
                    self.new_hosts[key_host].status_information = n["status_information"]
                    self.new_hosts[key_host].site = n["site"]
                    self.new_hosts[key_host].address = n["address"]
                    self.new_hosts[key_host].notifications_disabled = n["notifications_disabled"]
                    self.new_hosts[key_host].scheduled_downtime = n["scheduled_downtime"]
                    self.new_hosts[key_host].passiveonly = n["passiveonly"]
                    self.new_hosts[key_host].acknowledged = n["acknowledged"]
                    self.new_hosts[key_host].flapping = n["flapping"]

        except ZabbixError:
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)


        # =========================================
        # services
        # =========================================
        services = []
        try:
            api_version = self.zapi.api_version()
        except ZabbixAPIException:
            # FIXME Is there a cleaner way to handle this? I just borrowed
            # this code from 80 lines ahead. -- AGV
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)

        try:
            try:
                # Get a list of all issues (AKA tripped triggers)
                # Zabbix 3+ returns array of objects
                triggers = self.zapi.trigger.get({'only_true': True,
                                            'skipDependent': True,
                                            'monitored': True,
                                            'active': True,
                                            'output': 'extend',
                                            'expandDescription': True,
                                            'selectHosts': ['hostid','host','name'],
                                            'selectItems': ['itemid','name','key_','lastvalue','state','lastclock'],  # thats for zabbix api 2.0+
                                            'filter': {'value': 1},
                                             })

                # Do another query to find out which issues are Unacknowledged
                # Zabbix 3+ returns array of objects
                unack_triggers = self.zapi.trigger.get({'only_true': True,
                                                        'skipDependent': True,
                                                        'monitored': True,
                                                        'active': True,
                                                        'output': ['triggerid'],
                                                        'expandDescription': True,
                                                        'selectHosts': ['hostid'],
                                                        'withLastEventUnacknowledged': True,
                                                  })
                unack_trigger_ids = [u['triggerid'] for u in unack_triggers]
                
                for t in triggers:
                    t['acknowledged'] = False if t['triggerid'] in unack_trigger_ids else True
                    
                    # get Application name for the trigger
                    this_item = self.zapi.item.get(
                        {'itemids': [t['items'][0]['itemid']],
                         'output': ['itemid', 'hostid', 'name', 'lastvalue'],
                         'selectApplications': 'extend'}
                    )
                    t['application'] = self.getLastApp(this_item)
                    try:
                        t['lastvalue']   = this_item[0]['lastvalue']
                    except IndexError as e:
                        self.Debug(server=self.get_name(), debug="ItemID '%s' has no values" %
                            t['items'][0]['itemid'], head='WARNING')

                    services.append(t)

            except ZabbixAPIException:
                # FIXME Is there a cleaner way to handle this? I just borrowed
                # this code from 80 lines ahead. -- AGV
                # set checking flag back to False
                self.isChecking = False
                result, error = self.Error(sys.exc_info())
                print(sys.exc_info())
                return Result(result=result, error=error)

            except ZabbixError as e:
                if e.terminate:
                    return e.result
                else:
                    service = e.result.content
                    ret = e.result

            for service in services:
                # Zabbix probably shows OK services too - kick 'em!
                # UPDATE Zabbix api 3.0 doesn't but I didn't tried with older
                #        so I left it
                status = self.statemap.get(service['priority'], service['priority'])
                # self.Debug(server=self.get_name(), debug="SERVICE (" + service['application'] + ") STATUS: **" + status + "** PRIORITY: #" + service['priority'])
                # self.Debug(server=self.get_name(), debug="-----======== SERVICE " + str(service))
                if not status == 'OK':
                    if not service['description'].endswith('...'):
                        state = service['description']
                    else:
                        state = service['items'][0]['lastvalue']
                    # A trigger can be triggered by multiple items
                    # Get last checking date of any of the items involved
                    lastcheck = 0
                    for item in service['items']:
                        if int(item['lastclock']) > lastcheck:
                            lastcheck = int(item['lastclock'])

                    if self.use_description_name_service and \
                            len(service['comments']) != 0:
                        srvc = self.nagiosify_service(service['comments'])
                    else:
                        srvc = service['application']

                    n = {
                        'host': '',
                        'hostname': '',
                        'service': service['triggerid'],
                        'server':  self.name,
                        'status':  status,
                        # Putting service in attempt column allow to see it in GUI
                        'attempt': srvc,
                        'duration': HumanReadableDurationFromTimestamp(service['lastchange']),
                        'status_information': state,
                        'last_check': time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(lastcheck)),
                        'site': '',
                        'command': 'zabbix',
                        # status flags
                        'passiveonly': False,
                        'notifications_disabled': False,
                        'flapping': False,
                        'acknowledged' : service['acknowledged'],
                        'scheduled_downtime': False,
                        # Zabbix data
                        'triggerid': service['triggerid'],
                    }

                    n['hostid']   = service['hosts'][0]['hostid']
                    n['host']     = service['hosts'][0]['host']
                    n['hostname'] = service['hosts'][0]['name']

                    key = n["hostname"] if len(n['hostname']) != 0 else n["host"];
                    #key = n["hostid"];

                    if self.new_hosts[key].scheduled_downtime == True:
                        n['scheduled_downtime'] = True

                    nagitems["services"].append(n)
                    
                    # after collection data in nagitems create objects of its informations
                    # host objects contain service objects
                    # if not created previously, host should be created with proper data
                    if key not in self.new_hosts:
                        # This should never happen, because we've stored all hosts in new_hosts array
                        print("================================")
                        print("Host " + key + "Not found in host cache")
                        if conf.debug_mode is True:
                            self.Debug(server=self.get_name(), debug="Host not found [" + key + "]")

                    # if a service does not exist create its object
                    new_service = n["triggerid"]
                    if new_service not in self.new_hosts[key].services:
                        self.new_hosts[key].services[new_service] = GenericService()
                        
                        self.new_hosts[key].services[new_service].host       = n["hostname"] if len(n['hostname']) != 0 else n["host"]
                        self.new_hosts[key].services[new_service].name       = n["service"]
                        self.new_hosts[key].services[new_service].status     = n["status"]
                        self.new_hosts[key].services[new_service].last_check = n["last_check"]
                        self.new_hosts[key].services[new_service].duration   = n["duration"]
                        self.new_hosts[key].services[new_service].attempt    = n["attempt"]
                        self.new_hosts[key].services[new_service].status_information = n["status_information"]
                        self.new_hosts[key].services[new_service].passiveonly = n["passiveonly"]
                        self.new_hosts[key].services[new_service].notifications_disabled = n["notifications_disabled"]
                        self.new_hosts[key].services[new_service].flapping     = n["flapping"]
                        self.new_hosts[key].services[new_service].acknowledged = n["acknowledged"]
                        self.new_hosts[key].services[new_service].scheduled_downtime = n["scheduled_downtime"]
                        self.new_hosts[key].services[new_service].site         = n["site"]
                        self.new_hosts[key].services[new_service].address      = self.new_hosts[key].address
                        self.new_hosts[key].services[new_service].command      = n["command"]
                        self.new_hosts[key].services[new_service].hostid       = n["hostid"]
                        self.new_hosts[key].services[new_service].triggerid    = n["triggerid"]
                        if conf.debug_mode is True:
                            self.Debug(server=self.get_name(), debug="Adding new service[" + new_service + "] **" + n['service'] + "**")

        except (ZabbixError, ZabbixAPIException):
            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            print(sys.exc_info())
            return Result(result=result, error=error)
        
        return ret
Esempio n. 27
0
    def _get_status(self):
        """
            Get status from Checkmk Server
        """

        ret = Result()

        # Create URLs for the configured filters
        url_params = ''

        if self.force_authuser:
            url_params += "&force_authuser=1"

        url_params += '&is_host_acknowledged=-1&is_service_acknowledged=-1'
        url_params += '&is_host_notifications_enabled=-1&is_service_notifications_enabled=-1'
        url_params += '&is_host_active_checks_enabled=-1&is_service_active_checks_enabled=-1'
        url_params += '&host_scheduled_downtime_depth=-1&is_in_downtime=-1'

        try:
            response = []
            try:
                response = self._get_url(self.urls['api_hosts'] + url_params)
            except MultisiteError as e:
                if e.terminate:
                    return e.result

            if response == '':
                return Result(result='',
                              error='Login failed',
                              status_code=401)

            for row in response[1:]:
                host= dict(list(zip(copy.deepcopy(response[0]), copy.deepcopy(row))))
                n = {
                    'host':               host['host'],
                    'status':             self.statemap.get(host['host_state'], host['host_state']),
                    'last_check':         host['host_check_age'],
                    'duration':           host['host_state_age'],
                    'status_information': html.unescape(host['host_plugin_output'].replace('\n', ' ')),
                    'attempt':            host['host_attempt'],
                    'site':               host['sitename_plain'],
                    'address':            host['host_address']
                }

                # host objects contain service objects
                if n['host'] not in self.new_hosts:
                    new_host = n['host']
                    self.new_hosts[new_host] = GenericHost()
                    self.new_hosts[new_host].name = n['host']
                    self.new_hosts[new_host].server = self.name
                    self.new_hosts[new_host].status = n['status']
                    self.new_hosts[new_host].last_check = n['last_check']
                    self.new_hosts[new_host].duration = n['duration']
                    self.new_hosts[new_host].attempt = n['attempt']
                    self.new_hosts[new_host].status_information= html.unescape(n['status_information'].replace('\n', ' '))
                    self.new_hosts[new_host].site = n['site']
                    self.new_hosts[new_host].address = n['address']

                    # transisition to Checkmk 1.1.10p2
                    if 'host_in_downtime' in host:
                        if host['host_in_downtime'] == 'yes':
                            self.new_hosts[new_host].scheduled_downtime = True
                    if 'host_acknowledged' in host:
                        if host['host_acknowledged'] == 'yes':
                            self.new_hosts[new_host].acknowledged = True
                    if 'host_notifications_enabled' in host:
                        if host['host_notifications_enabled'] == 'no':
                            self.new_hosts[new_host].notifications_disabled = True

                    # hard/soft state for later filter evaluation
                    real_attempt, max_attempt = self.new_hosts[new_host].attempt.split('/')
                    if real_attempt != max_attempt:
                        self.new_hosts[new_host].status_type = 'soft'
                    else:
                        self.new_hosts[new_host].status_type = 'hard'

            del response

        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        # Add filters to the url which should only be applied to the service request
        if conf.filter_services_on_unreachable_hosts == True:
            # thanks to https://github.com/HenriWahl/Nagstamon/issues/510
            url_params += '&hst0=On&hst1=On'

        # services
        try:
            response = []
            try:
                response = self._get_url(self.urls['api_services'] + url_params)
            except MultisiteError as e:
                if e.terminate:
                    return e.result
                else:
                    response = copy.deepcopy(e.result.content)
                    ret = copy.deepcopy(e.result)

            for row in response[1:]:
                service = dict(list(zip(copy.deepcopy(response[0]), copy.deepcopy(row))))
                n = {
                    'host':               service['host'],
                    'service':            service['service_description'],
                    'status':             self.statemap.get(service['service_state'], service['service_state']),
                    'last_check':         service['svc_check_age'],
                    'duration':           service['svc_state_age'],
                    'attempt':            service['svc_attempt'],
                    'status_information': html.unescape(service['svc_plugin_output'].replace('\n', ' ')),
                    # Checkmk passive services can be re-scheduled by using the Checkmk service
                    'passiveonly':        service['svc_is_active'] == 'no' and not service['svc_check_command'].startswith('check_mk'),
                    'flapping':           service['svc_flapping'] == 'yes',
                    'site':               service['sitename_plain'],
                    'address':            service['host_address'],
                    'command':            service['svc_check_command'],
                }

                # host objects contain service objects
                if n['host'] not in self.new_hosts:
                    self.new_hosts[n['host']] = GenericHost()
                    self.new_hosts[n['host']].name = n['host']
                    self.new_hosts[n['host']].status = 'UP'
                    self.new_hosts[n['host']].site = n['site']
                    self.new_hosts[n['host']].address = n['address']
                # if a service does not exist create its object
                if n['service'] not in self.new_hosts[n['host']].services:
                    new_service = n['service']
                    self.new_hosts[n['host']].services[new_service] = GenericService()
                    self.new_hosts[n['host']].services[new_service].host = n['host']
                    self.new_hosts[n['host']].services[new_service].server = self.name
                    self.new_hosts[n['host']].services[new_service].name = n['service']
                    self.new_hosts[n['host']].services[new_service].status = n['status']
                    self.new_hosts[n['host']].services[new_service].last_check = n['last_check']
                    self.new_hosts[n['host']].services[new_service].duration = n['duration']
                    self.new_hosts[n['host']].services[new_service].attempt = n['attempt']
                    self.new_hosts[n['host']].services[new_service].status_information = n['status_information'].strip()
                    self.new_hosts[n['host']].services[new_service].passiveonly = n['passiveonly']
                    self.new_hosts[n['host']].services[new_service].flapping = n['flapping']
                    self.new_hosts[n['host']].services[new_service].site = n['site']
                    self.new_hosts[n['host']].services[new_service].address = n['address']
                    self.new_hosts[n['host']].services[new_service].command = n['command']

                    # transistion to Checkmk 1.1.10p2
                    if 'svc_in_downtime' in service:
                        if service['svc_in_downtime'] == 'yes':
                            self.new_hosts[n['host']].services[new_service].scheduled_downtime = True
                    if 'svc_acknowledged' in service:
                        if service['svc_acknowledged'] == 'yes':
                            self.new_hosts[n['host']].services[new_service].acknowledged = True
                    if 'svc_flapping' in service:
                        if service['svc_flapping'] == 'yes':
                            self.new_hosts[n['host']].services[new_service].flapping = True
                    if 'svc_notifications_enabled' in service:
                        if service['svc_notifications_enabled'] == 'no':
                            self.new_hosts[n['host']].services[new_service].notifications_disabled = True

                    # hard/soft state for later filter evaluation
                    real_attempt, max_attempt = self.new_hosts[n['host']].services[new_service].attempt.split('/')
                    if real_attempt != max_attempt:
                        self.new_hosts[n['host']].services[new_service].status_type = 'soft'
                    else:
                        self.new_hosts[n['host']].services[new_service].status_type = 'hard'

            del response

        except:
            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=copy.deepcopy(result), error=copy.deepcopy(error))

        del url_params

        return ret
Esempio n. 28
0
    def _get_status(self):
        """
            Get status from Opsview Server
        """
        # following http://docs.opsview.org/doku.php?id=opsview3.4:api to get ALL services in ALL states except OK
        # because we filter them out later
        # the API seems not to let hosts information directly, we hope to get it from service informations
        try:
            result = self.FetchURL(
                self.monitor_url +
                "/api/status/service?state=1&state=2&state=3",
                giveback="xml")
            xmlobj, error = result.result, result.error
            if error != "":
                return Result(result=xmlobj, error=copy.deepcopy(error))

            for host in xmlobj.data.findAll('list'):
                # host
                hostdict = host.attrs
                self.new_hosts[str(hostdict["name"])] = GenericHost()
                self.new_hosts[str(hostdict["name"])].name = str(
                    hostdict["name"])
                self.new_hosts[str(hostdict["name"])].server = self.name
                # states come in lower case from Opsview
                self.new_hosts[str(hostdict["name"])].status = str(
                    hostdict["state"].upper())
                self.new_hosts[str(hostdict["name"])].status_type = str(
                    hostdict["state_type"])
                self.new_hosts[str(hostdict["name"])].last_check = str(
                    hostdict["last_check"])
                self.new_hosts[str(
                    hostdict["name"]
                )].duration = HumanReadableDurationFromSeconds(
                    hostdict["state_duration"])
                self.new_hosts[str(hostdict["name"])].attempt = str(
                    hostdict["current_check_attempt"]) + "/" + str(
                        hostdict["max_check_attempts"])
                self.new_hosts[str(hostdict["name"])].status_information = str(
                    hostdict["output"].replace("\n", " "))
                # if host is in downtime add it to known maintained hosts
                if hostdict["downtime"] == "2":
                    self.new_hosts[str(
                        hostdict["name"])].scheduled_downtime = True
                if 'acknowledged' in hostdict:
                    self.new_hosts[str(hostdict["name"])].acknowledged = True
                if 'flapping' in hostdict:
                    self.new_hosts[str(hostdict["name"])].flapping = True

                #services
                for service in host.findAll("services"):
                    servicedict = service.attrs
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])] = OpsviewService()
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].host = str(hostdict["name"])
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].name = str(servicedict["name"])
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].server = self.name
                    # states come in lower case from Opsview
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].status = str(
                            servicedict["state"].upper())
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].status_type = str(
                            servicedict["state_type"])
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].last_check = str(
                            servicedict["last_check"])
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"]
                    )].duration = HumanReadableDurationFromSeconds(
                        servicedict["state_duration"])
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].attempt = str(
                            servicedict["current_check_attempt"]) + "/" + str(
                                servicedict["max_check_attempts"])
                    self.new_hosts[str(hostdict["name"])].services[str(
                        servicedict["name"])].status_information = str(
                            servicedict["output"].replace("\n", " "))
                    if servicedict['downtime'] == "2":
                        self.new_hosts[str(hostdict["name"])].services[str(
                            servicedict["name"])].scheduled_downtime = True
                    if 'acknowledged' in servicedict:
                        self.new_hosts[str(hostdict["name"])].services[str(
                            servicedict["name"])].acknowledged = True
                    if 'flapping' in servicedict:
                        self.new_hosts[str(hostdict["name"])].services[str(
                            servicedict["name"])].flapping = True

                    # extra opsview id for service, needed for submitting check results
                    self.new_hosts[str(str(hostdict["name"]))].services[str(
                        str(servicedict["name"]))].service_object_id = str(
                            servicedict["service_object_id"])
                del servicedict
                del hostdict

        except:

            import traceback
            traceback.print_exc(file=sys.stdout)

            # set checking flag back to False
            self.isChecking = False
            result, error = self.Error(sys.exc_info())
            return Result(result=result, error=error)

        #dummy return in case all is OK
        return Result()