#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------------
# This file is part of Mentat system (https://mentat.cesnet.cz/).
#
# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
# Use of this source is governed by the MIT license, see LICENSE file.
# -------------------------------------------------------------------------------
"""
This file contains pluggable module for Hawat web interface containing features
related to real time dashboard calculations for `IDEA <https://idea.cesnet.cz/en/index>`__
events. This module is currently experimental, because the searching and statistical
calculations can be very performance demanding.
"""
__author__ = "Jan Mach <jan.mach@cesnet.cz>"
__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
import datetime
import pytz
import flask
from flask_babel import lazy_gettext
import mentat.stats.idea
import mentat.services.eventstorage
import hawat.events
import hawat.const
import hawat.acl
import hawat.menu
from hawat.base import HawatBlueprint
from hawat.view import BaseSearchView
from hawat.view.mixin import HTMLMixin, AJAXMixin
from hawat.base import PsycopgMixin
from hawat.blueprints.hosts.forms import SimpleHostSearchForm
BLUEPRINT_NAME = 'hosts'
"""Name of the blueprint as module global constant."""
[docs]class AbstractSearchView(PsycopgMixin, BaseSearchView): # pylint: disable=locally-disabled,abstract-method
"""
Base class for view responsible for searching...
"""
authentication = True
authorization = [hawat.acl.PERMISSION_POWER]
[docs] @classmethod
def get_view_title(cls, **kwargs):
return lazy_gettext('Search hosts')
[docs] @classmethod
def get_view_icon(cls):
return 'module-{}'.format(cls.module_name)
[docs] def do_after_search(self, items):
self.logger.debug(
"Calculating host statistics from %d records.",
len(items)
)
if items:
dt_from = self.response_context['form_data'].get('dt_from', None)
if dt_from:
dt_from = dt_from.astimezone(pytz.utc)
dt_from = dt_from.replace(tzinfo=None)
dt_to = self.response_context['form_data'].get('dt_to', None)
if dt_to:
dt_to = dt_to.astimezone(pytz.utc)
dt_to = dt_to.replace(tzinfo=None)
if not dt_from and items:
dt_from = self.get_db().search_column_with('detecttime')
if not dt_to and items:
dt_to = datetime.datetime.utcnow()
self.response_context.update(
statistics=mentat.stats.idea.evaluate_singlehost_events(
self.response_context['form_data'].get('host_addr'),
items,
dt_from=dt_from,
dt_to=dt_to,
max_count=flask.current_app.config['HAWAT_CHART_TIMELINE_MAXSTEPS'],
timezone=pytz.timezone(flask.session.get('timezone', 'UTC'))
)
)
self.response_context.pop('items', None)
[docs] def do_before_response(self, **kwargs):
self.response_context.update(
quicksearch_list=self.get_quicksearch_by_time()
)
[docs] @staticmethod
def get_event_factory():
return mentat.services.eventstorage.record_to_idea_ghost
[docs] @staticmethod
def get_event_columns():
columns = list(mentat.services.eventstorage.EVENTS_COLUMNS)
columns.remove('event')
return columns
[docs]class SearchView(HTMLMixin, AbstractSearchView): # pylint: disable=locally-disabled,too-many-ancestors
"""
View responsible for querying `IDEA <https://idea.cesnet.cz/en/index>`__
event database and presenting the results in the form of HTML page.
"""
methods = ['GET']
[docs]class APISearchView(AJAXMixin, AbstractSearchView): # pylint: disable=locally-disabled,too-many-ancestors
"""
View responsible for querying `IDEA <https://idea.cesnet.cz/en/index>`__
event database and presenting the results in the form of JSON document.
"""
methods = ['GET', 'POST']
[docs] @classmethod
def get_view_name(cls):
return 'apisearch'
# -------------------------------------------------------------------------------
[docs]class HostsBlueprint(HawatBlueprint):
"""Pluggable module - Host overview (*hosts*)."""
[docs] @classmethod
def get_module_title(cls):
return lazy_gettext('Host overview')
[docs] def register_app(self, app):
app.menu_main.add_entry(
'view',
'developer.{}'.format(BLUEPRINT_NAME),
position=80,
view=SearchView
)
# -------------------------------------------------------------------------------
[docs]def get_blueprint():
"""
Mandatory interface for :py:mod:`hawat.Hawat` and factory function. This function
must return a valid instance of :py:class:`hawat.app.HawatBlueprint` or
:py:class:`flask.Blueprint`.
"""
hbp = HostsBlueprint(
BLUEPRINT_NAME,
__name__,
template_folder='templates'
)
hbp.register_view_class(SearchView, '/{}/search'.format(BLUEPRINT_NAME))
hbp.register_view_class(APISearchView, '/api/{}/search'.format(BLUEPRINT_NAME))
return hbp