Revision cf3c2494
Chaque plugin adresse désormais une seule requête à la base de données pour tous les évènements de la page, plutôt qu'une requête par évènement.
git-svn-id: https://vigilo-dev.si.c-s.fr/svn@6291 b22e2e97-25c9-44ff-b637-2e5ceca36478
vigiboard/config/app_cfg.py | ||
---|---|---|
37 | 37 |
import vigiboard |
38 | 38 |
from vigiboard.lib import app_globals, helpers |
39 | 39 |
|
40 |
import logging |
|
41 |
LOGGER = logging.getLogger(__name__) |
|
42 |
|
|
40 | 43 |
class VigiboardConfig(VigiloAppConfig): |
41 | 44 |
def setup_sqlalchemy(self): |
42 | 45 |
super(VigiboardConfig, self).setup_sqlalchemy() |
... | ... | |
62 | 65 |
plugin_class = ep.load(require=True) |
63 | 66 |
if issubclass(plugin_class, VigiboardRequestPlugin): |
64 | 67 |
plugins.append((unicode(ep.name), plugin_class())) |
65 |
except: |
|
66 |
# @TODO: lever une erreur ?
|
|
67 |
pass |
|
68 |
except Exception, e:
|
|
69 |
LOGGER.error('Unable to import plugin %s : %s' % (plugin_name, e))
|
|
70 |
|
|
68 | 71 |
config['columns_plugins'] = plugins |
69 | 72 |
|
70 | 73 |
base_config = VigiboardConfig('vigiboard') |
vigiboard/controllers/plugins/__init__.py | ||
---|---|---|
42 | 42 |
self.style = style |
43 | 43 |
self.object_name = object_name |
44 | 44 |
|
45 |
def get_value(self, idcorrevent, *args, **kwargs):
|
|
45 |
def get_bulk_data(self, events_ids):
|
|
46 | 46 |
""" |
47 |
Cette méthode est appelée lorsque l'on demande la valeur du plugin |
|
48 |
grâce à la méthode get_plugin_value du L{RootController} de VigiBoard. |
|
47 |
Cette méthode est appelée par le L{RootController} : elle |
|
48 |
retourne toutes les données affichées par le plugin dans le |
|
49 |
tableau des évènements de la page principale de VigiBoard. |
|
49 | 50 |
|
50 | 51 |
Cette méthode DEVRAIT être surchargée dans les classes dérivées. |
51 | 52 |
|
53 |
@param event_ids: Liste des identifiants des C{CorrEvent} affichés |
|
54 |
sur la page. |
|
55 |
@type events_id: C{List} of C{int} |
|
56 |
@return: Dictionnaire associant à chaque identifiant |
|
57 |
d'évènement les données à afficher par le plugin. |
|
58 |
@rtype: C{dict} |
|
59 |
""" |
|
60 |
pass |
|
61 |
|
|
62 |
def get_json_data(self, idcorrevent, *args, **kwargs): |
|
63 |
""" |
|
64 |
Cette méthode est appelée par le template du plugin via |
|
65 |
la méthode get_plugin_json_data du L{RootController} de VigiBoard. |
|
66 |
|
|
67 |
Cette méthode DEVRAIT être surchargée dans les classes dérivées |
|
68 |
si le plugin en question doit avoir recours à une requête JSON. |
|
69 |
|
|
52 | 70 |
@param idcorrevent: Identifiant du C{CorrEvent} à interroger. |
53 |
@type idcorrevent: C{int} |
|
71 |
@type idcorrevent: C{int}
|
|
54 | 72 |
@return: Dictionnaire contenant la ou les valeur(s) correspondantes. |
55 |
@rtype: C{dict} |
|
73 |
@rtype: C{dict}
|
|
56 | 74 |
""" |
57 | 75 |
pass |
58 | 76 |
|
vigiboard/controllers/plugins/details.py | ||
---|---|---|
40 | 40 |
externes. |
41 | 41 |
""" |
42 | 42 |
|
43 |
def get_value(self, idcorrevent, *args, **kwargs):
|
|
43 |
def get_json_data(self, idcorrevent, *args, **kwargs):
|
|
44 | 44 |
""" |
45 | 45 |
Renvoie les éléments pour l'affichage de la fenêtre de dialogue |
46 | 46 |
contenant des détails sur un événement corrélé. |
vigiboard/controllers/plugins/hls.py | ||
---|---|---|
25 | 25 |
|
26 | 26 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
27 | 27 |
from vigilo.models.session import DBSession |
28 |
from vigilo.models.tables import HighLevelService, CorrEvent, Event, SupItem |
|
28 |
from vigilo.models.tables import HighLevelService, CorrEvent, Event, SupItem, \ |
|
29 |
ImpactedHLS, ImpactedPath |
|
30 |
from sqlalchemy.orm import aliased |
|
31 |
from sqlalchemy.sql import functions |
|
29 | 32 |
|
30 | 33 |
class PluginHLS(VigiboardRequestPlugin): |
31 | 34 |
""" |
32 | 35 |
Plugin qui permet de voir les services de haut niveau impactés par |
33 |
un événement.
|
|
36 |
les événements affichés sur la page principale de VigiBoard.
|
|
34 | 37 |
""" |
35 |
def get_value(self, idcorrevent): |
|
38 |
|
|
39 |
def get_bulk_data(self, events_ids): |
|
36 | 40 |
""" |
37 |
Renvoie le nom des services de haut niveau impactés par l'événement. |
|
41 |
Renvoie le nom des services de haut niveau impactés |
|
42 |
par chacun des événements du tableau de VigiBoard. |
|
38 | 43 |
|
39 |
@param idcorrevent: Identifiant de l'événement corrélé. |
|
40 |
@type idcorrevent: C{int} |
|
41 |
@return: Un dictionnaire dont la clé "services" contient une liste |
|
42 |
des noms des services de haut niveau impactés par l'événement |
|
43 |
corrélé dont l'identifiant est L{idcorrevent}. |
|
44 |
@param events_ids: Liste des identifiants des événements corrélés |
|
45 |
à afficher. |
|
46 |
@type events_ids: C{int} |
|
47 |
@return: Un dictionnaire associant à chaque identifiant d'évènement |
|
48 |
la liste des noms des HLS de plus haut niveau qu'il impacte. |
|
49 |
@rtype: C{dict} |
|
44 | 50 |
""" |
45 |
supitem = self.get_correvent_supitem(idcorrevent) |
|
46 | 51 |
|
47 |
if not supitem: |
|
48 |
return [] |
|
52 |
imp_hls1 = aliased(ImpactedHLS) |
|
53 |
imp_hls2 = aliased(ImpactedHLS) |
|
54 |
|
|
55 |
# Sous-requête récupérant les identifiants des supitems |
|
56 |
# impactés par les évènements passés en paramètre. |
|
57 |
subquery = DBSession.query( |
|
58 |
SupItem.idsupitem, |
|
59 |
CorrEvent.idcorrevent |
|
60 |
).join( |
|
61 |
(Event, Event.idsupitem == SupItem.idsupitem), |
|
62 |
(CorrEvent, CorrEvent.idcause == Event.idevent), |
|
63 |
).filter(CorrEvent.idcorrevent.in_(events_ids) |
|
64 |
).subquery() |
|
65 |
|
|
66 |
# Sous-requête récupérant les identifiants des SHN de plus |
|
67 |
# haut niveau impactés par les évènements passés en paramètre. |
|
68 |
# Fait appel à la sous-requête précédente (subquery). |
|
69 |
subquery2 = DBSession.query( |
|
70 |
functions.max(imp_hls1.distance).label('distance'), |
|
71 |
imp_hls1.idpath, |
|
72 |
subquery.c.idcorrevent |
|
73 |
).join( |
|
74 |
(ImpactedPath, ImpactedPath.idpath == imp_hls1.idpath) |
|
75 |
).join( |
|
76 |
(subquery, ImpactedPath.idsupitem == subquery.c.idsupitem) |
|
77 |
).group_by(imp_hls1.idpath, subquery.c.idcorrevent |
|
78 |
).subquery() |
|
49 | 79 |
|
50 |
services = supitem.impacted_hls( |
|
51 |
HighLevelService.servicename |
|
52 |
).distinct().order_by( |
|
80 |
# Requête récupérant les noms des SHN de plus haut niveau |
|
81 |
# impactés par chacun des évènements passés en paramètre. |
|
82 |
# Fait appel à la sous-requête précédente (subquery2). |
|
83 |
services = DBSession.query( |
|
84 |
HighLevelService.servicename, |
|
85 |
subquery2.c.idcorrevent |
|
86 |
).join( |
|
87 |
(imp_hls2, HighLevelService.idservice == imp_hls2.idhls), |
|
88 |
(subquery2, subquery2.c.idpath == imp_hls2.idpath), |
|
89 |
).filter(imp_hls2.distance == subquery2.c.distance |
|
90 |
).order_by( |
|
53 | 91 |
HighLevelService.servicename.asc() |
54 | 92 |
).all() |
55 | 93 |
|
56 |
return {'services': [service.servicename for service in services]} |
|
94 |
# Construction d'un dictionnaire associant à chaque évènement |
|
95 |
# le nom des SHN de plus haut niveau qu'il impacte. |
|
96 |
hls = {} |
|
97 |
for event_id in events_ids: |
|
98 |
hls[event_id] = [] |
|
99 |
for service in services: |
|
100 |
hls[service.idcorrevent].append(service.servicename) |
|
101 |
|
|
102 |
return hls |
|
57 | 103 |
|
58 |
def get_correvent_supitem(self, idcorrevent): |
|
59 |
""" |
|
60 |
Retourne le supitem ayant causé l'évènement |
|
61 |
corrélé dont l'identifiant est passé en paramètre. |
|
62 |
""" |
|
63 |
# On récupère l'item recherché dans la BDD |
|
64 |
supitem = DBSession.query(SupItem |
|
65 |
).join( |
|
66 |
(Event, Event.idsupitem == SupItem.idsupitem), |
|
67 |
(CorrEvent, CorrEvent.idcause == Event.idevent), |
|
68 |
).filter(CorrEvent.idcorrevent == idcorrevent).first() |
|
69 |
return supitem |
vigiboard/controllers/plugins/test.py | ||
---|---|---|
32 | 32 |
"Hello world" pour chaque événement du tableau. |
33 | 33 |
""" |
34 | 34 |
|
35 |
def get_value(self, idcorrevent, *args, **kwargs):
|
|
35 |
def get_bulk_data(self, events_ids):
|
|
36 | 36 |
""" |
37 |
Cette méthode est appelée depuis le template associé à ce plugin, |
|
38 |
mais également lorsque l'on demande la valeur du plugin grâce à la |
|
39 |
méthode get_plugin_value du L{RootController} de VigiBoard. |
|
37 |
Cette méthode est appelée par le L{RootController} de VigiBoard. |
|
38 |
Elle renvoie les données à afficher pour chaque évènement. |
|
40 | 39 |
|
41 |
@param idcorrevent: Identifiant du C{CorrEvent} à interroger. |
|
42 |
@type idcorrevent: C{int} |
|
43 |
@return: Dictionnaire contenant un texte statique. |
|
44 |
@rtype: C{dict} |
|
40 |
@param events_ids: Liste des identifiants des événements corrélés |
|
41 |
à afficher. |
|
42 |
@type events_ids: C{int} |
|
43 |
@return: Un dictionnaire associant à chaque identifiant d'évènement |
|
44 |
un texte statique. |
|
45 |
@rtype: C{dict} |
|
45 | 46 |
""" |
46 |
return {'text': 'Hello world'} |
|
47 |
plugin_data = {} |
|
48 |
for event in events_ids: |
|
49 |
plugin_data[event] = 'Hello world' |
|
50 |
|
|
51 |
return plugin_data |
|
52 |
|
vigiboard/controllers/root.py | ||
---|---|---|
32 | 32 |
from sqlalchemy import asc |
33 | 33 |
from sqlalchemy.sql import func |
34 | 34 |
from sqlalchemy.orm import aliased |
35 |
from sqlalchemy.orm import contains_eager |
|
35 | 36 |
from repoze.what.predicates import Any, All, in_group, \ |
36 | 37 |
has_permission, not_anonymous, \ |
37 | 38 |
NotAuthorizedError |
... | ... | |
135 | 136 |
""" |
136 | 137 |
user = get_current_user() |
137 | 138 |
aggregates = VigiboardRequest(user) |
139 |
|
|
138 | 140 |
aggregates.add_table( |
139 | 141 |
CorrEvent, |
140 | 142 |
aggregates.items.c.hostname, |
141 | 143 |
aggregates.items.c.servicename |
142 | 144 |
) |
143 | 145 |
aggregates.add_join((Event, CorrEvent.idcause == Event.idevent)) |
146 |
aggregates.add_contains_eager(CorrEvent.cause) |
|
147 |
aggregates.add_group_by(Event) |
|
144 | 148 |
aggregates.add_join((aggregates.items, |
145 | 149 |
Event.idsupitem == aggregates.items.c.idsupitem)) |
146 | 150 |
aggregates.add_order_by(asc(aggregates.items.c.hostname)) |
... | ... | |
228 | 232 |
else: |
229 | 233 |
id_first_row += 1 |
230 | 234 |
|
235 |
# Récupération des données des plugins |
|
236 |
plugins_data = {} |
|
237 |
plugins = dict(config['columns_plugins']) |
|
238 |
for plugin in plugins: |
|
239 |
plugin_data = plugins[plugin].get_bulk_data( |
|
240 |
[event[0].idcorrevent for event in aggregates.events] |
|
241 |
) |
|
242 |
if plugin_data : |
|
243 |
plugins_data[plugin] = plugin_data |
|
244 |
|
|
231 | 245 |
return dict( |
232 | 246 |
hostname = None, |
233 | 247 |
servicename = None, |
234 | 248 |
events = aggregates.events, |
249 |
plugins_data = plugins_data, |
|
235 | 250 |
rows_info = { |
236 | 251 |
'id_first_row': id_first_row, |
237 | 252 |
'id_last_row': id_last_row, |
... | ... | |
293 | 308 |
SupItem, |
294 | 309 |
).join( |
295 | 310 |
(Event, Event.idsupitem == SupItem.idsupitem), |
296 |
(EVENTSAGGREGATE_TABLE, EVENTSAGGREGATE_TABLE.c.idevent == |
|
297 |
Event.idevent), |
|
298 |
(CorrEvent, CorrEvent.idcorrevent == |
|
299 |
EVENTSAGGREGATE_TABLE.c.idcorrevent), |
|
311 |
(CorrEvent, Event.idevent == CorrEvent.idcause), |
|
300 | 312 |
).filter(CorrEvent.idcorrevent == idcorrevent |
301 |
).filter(Event.idevent == CorrEvent.idcause |
|
302 | 313 |
).one() |
303 | 314 |
|
304 | 315 |
if isinstance(cause_supitem, LowLevelService): |
... | ... | |
334 | 345 |
hostname = hostname, |
335 | 346 |
servicename = servicename, |
336 | 347 |
events = events.events, |
348 |
plugins_data = {}, |
|
337 | 349 |
rows_info = { |
338 | 350 |
'id_first_row': id_first_row, |
339 | 351 |
'id_last_row': id_last_row, |
... | ... | |
413 | 425 |
idevent = idevent, |
414 | 426 |
hostname = event.hostname, |
415 | 427 |
servicename = event.servicename, |
428 |
plugins_data = {}, |
|
416 | 429 |
rows_info = { |
417 | 430 |
'id_first_row': id_first_row, |
418 | 431 |
'id_last_row': id_last_row, |
... | ... | |
492 | 505 |
hostname = host, |
493 | 506 |
servicename = service, |
494 | 507 |
events = aggregates.events, |
508 |
plugins_data = {}, |
|
495 | 509 |
rows_info = { |
496 | 510 |
'id_first_row': id_first_row, |
497 | 511 |
'id_last_row': id_last_row, |
... | ... | |
675 | 689 |
error_handler = handle_validation_errors_json) |
676 | 690 |
@expose('json') |
677 | 691 |
@require(access_restriction) |
678 |
def get_plugin_value(self, idcorrevent, plugin_name, *arg, **krgv):
|
|
692 |
def plugin_json(self, idcorrevent, plugin_name, *arg, **krgv):
|
|
679 | 693 |
""" |
680 | 694 |
Permet de récupérer la valeur d'un plugin associée à un CorrEvent |
681 | 695 |
donné via JSON. |
... | ... | |
700 | 714 |
raise HTTPNotFound(_('No such incident or insufficient ' |
701 | 715 |
'permissions')) |
702 | 716 |
|
703 |
return plugins[plugin_name].get_value(idcorrevent, *arg, **krgv)
|
|
717 |
return plugins[plugin_name].get_json_data(idcorrevent, *arg, **krgv)
|
|
704 | 718 |
|
705 | 719 |
@validate(validators={ |
706 | 720 |
"fontsize": validators.Regex( |
... | ... | |
754 | 768 |
# TODO: Utiliser un schéma de validation |
755 | 769 |
parent_id = int(parent_id) |
756 | 770 |
|
757 |
# On vérifie si le groupe parent fait partie des |
|
758 |
# groupes auxquel l'utilisateur a accès, et on |
|
759 |
# retourne une liste vide dans le cas contraire |
|
771 |
# On récupère la liste des groupes de supitems dont |
|
772 |
# l'identifiant du parent est passé en paramètre. |
|
773 |
supitem_groups = DBSession.query( |
|
774 |
SupItemGroup.idgroup, |
|
775 |
SupItemGroup.name, |
|
776 |
).join( |
|
777 |
(GroupHierarchy, |
|
778 |
GroupHierarchy.idchild == SupItemGroup.idgroup), |
|
779 |
).filter(GroupHierarchy.idparent == parent_id |
|
780 |
).filter(GroupHierarchy.idchild != parent_id) |
|
781 |
|
|
782 |
# Si l'utilisateur n'appartient pas au groupe 'managers', |
|
783 |
# on filtre les résultats en fonction de ses permissions. |
|
760 | 784 |
is_manager = in_group('managers').is_met(request.environ) |
761 | 785 |
if not is_manager: |
762 | 786 |
user = get_current_user() |
763 | 787 |
GroupHierarchy_aliased = aliased(GroupHierarchy, |
764 | 788 |
name='GroupHierarchy_aliased') |
765 |
supitem_groups = DBSession.query( |
|
766 |
SupItemGroup.idgroup, |
|
767 |
SupItemGroup.name, |
|
768 |
).join( |
|
769 |
(GroupHierarchy, |
|
770 |
GroupHierarchy.idchild == SupItemGroup.idgroup), |
|
771 |
(DataPermission, |
|
772 |
DataPermission.idgroup == GroupHierarchy.idparent), |
|
773 |
(USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \ |
|
774 |
DataPermission.idusergroup), |
|
775 |
).join( |
|
776 |
(GroupHierarchy_aliased, |
|
777 |
GroupHierarchy_aliased.idchild == SupItemGroup.idgroup), |
|
778 |
).filter(USER_GROUP_TABLE.c.username == user.user_name |
|
779 |
).filter(GroupHierarchy_aliased.idparent == parent_id |
|
780 |
).filter(GroupHierarchy_aliased.idchild != parent_id |
|
781 |
).distinct().all() |
|
789 |
supitem_groups.join( |
|
790 |
(GroupHierarchy_aliased, |
|
791 |
GroupHierarchy_aliased.idchild == SupItemGroup.idgroup), |
|
792 |
(DataPermission, |
|
793 |
DataPermission.idgroup == GroupHierarchy_aliased.idparent), |
|
794 |
(USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \ |
|
795 |
DataPermission.idusergroup), |
|
796 |
).filter(USER_GROUP_TABLE.c.username == user.user_name) |
|
782 | 797 |
|
783 | 798 |
groups = [] |
784 |
for group in supitem_groups: |
|
799 |
for group in supitem_groups.distinct().all():
|
|
785 | 800 |
groups.append({ |
786 | 801 |
'id' : group.idgroup, |
787 | 802 |
'name' : group.name, |
vigiboard/controllers/vigiboardrequest.py | ||
---|---|---|
30 | 30 |
|
31 | 31 |
from sqlalchemy import not_, and_, asc, desc |
32 | 32 |
from sqlalchemy.sql.expression import or_, null as expr_null, union_all |
33 |
from sqlalchemy.orm import contains_eager |
|
33 | 34 |
|
34 | 35 |
from vigilo.models.session import DBSession |
35 | 36 |
from vigilo.models.tables import Event, CorrEvent, EventHistory, \ |
... | ... | |
101 | 102 |
# Les managers ont accès à tout, les autres sont soumis |
102 | 103 |
# aux vérifications classiques d'accès aux données. |
103 | 104 |
if not is_manager: |
104 |
# user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]] |
|
105 |
# lls_query = lls_query.filter( |
|
106 |
# SUPITEM_GROUP_TABLE.c.idgroup.in_(user_groups) |
|
107 |
# ) |
|
108 |
# host_query = host_query.filter( |
|
109 |
# SUPITEM_GROUP_TABLE.c.idgroup.in_(user_groups) |
|
110 |
# ) |
|
111 | 105 |
|
112 | 106 |
lls_query = lls_query.join( |
113 | 107 |
(GroupHierarchy, |
... | ... | |
143 | 137 |
# Tables sur lesquelles porte la récupération (JOIN) |
144 | 138 |
self.join = [] |
145 | 139 |
|
140 |
# Options à ajouter la requête |
|
141 |
self.option = [] |
|
142 |
|
|
146 | 143 |
# Tables sur lesquelles porte la récupération (OUTER JOIN) |
147 | 144 |
self.outerjoin = [] |
148 | 145 |
|
... | ... | |
247 | 244 |
# query et join ont besoin de referrence |
248 | 245 |
self.req = self.req.query(*self.table) |
249 | 246 |
self.req = self.req.join(*self.join) |
247 |
self.req = self.req.options(*self.option) |
|
250 | 248 |
|
251 | 249 |
# le reste, non |
252 | 250 |
for i in self.outerjoin: |
... | ... | |
305 | 303 |
break |
306 | 304 |
self.join.append(i) |
307 | 305 |
|
306 |
def add_option(self, *argv): |
|
307 |
""" |
|
308 |
Ajoute une ou plusieurs options à la requête. |
|
309 |
|
|
310 |
@param argv: Liste des options à ajouter |
|
311 |
""" |
|
312 |
|
|
313 |
# On vérifie qu'il n'y a pas de doublons |
|
314 |
# dans la liste finale des options. |
|
315 |
|
|
316 |
for i in argv: |
|
317 |
for j in self.option: |
|
318 |
if str(i) == str(j): |
|
319 |
break |
|
320 |
self.option.append(i) |
|
321 |
|
|
322 |
def add_contains_eager(self, relation): |
|
323 |
""" |
|
324 |
Ajoute une option de type contains_eager à la |
|
325 |
requête pour la relation passée en paramètre. |
|
326 |
""" |
|
327 |
self.add_option(contains_eager(relation)) |
|
328 |
|
|
308 | 329 |
def add_outer_join(self, *argv): |
309 | 330 |
""" |
310 | 331 |
Ajoute une ou plusieurs jointures externes à |
vigiboard/tests/functional/plugins/test_details_plugin.py | ||
---|---|---|
141 | 141 |
"""Dialogue des détails avec un LLS et les bons droits.""" |
142 | 142 |
hostgroup, idcorrevent, idcause = insert_deps(True) |
143 | 143 |
|
144 |
response = self.app.post('/get_plugin_value', {
|
|
144 |
response = self.app.post('/plugin_json', {
|
|
145 | 145 |
'idcorrevent': idcorrevent, |
146 | 146 |
'plugin_name': 'details', |
147 | 147 |
}, extra_environ={'REMOTE_USER': 'access'}) |
... | ... | |
166 | 166 |
"""Dialogue des détails avec un hôte et les bons droits.""" |
167 | 167 |
hostgroup, idcorrevent, idcause = insert_deps(False) |
168 | 168 |
|
169 |
response = self.app.post('/get_plugin_value', {
|
|
169 |
response = self.app.post('/plugin_json', {
|
|
170 | 170 |
'idcorrevent': idcorrevent, |
171 | 171 |
'plugin_name': 'details', |
172 | 172 |
}, extra_environ={'REMOTE_USER': 'access'}) |
... | ... | |
195 | 195 |
# Le contrôleur renvoie une erreur 404 (HTTPNotFound) |
196 | 196 |
# lorsque l'utilisateur n'a pas les permissions nécessaires sur |
197 | 197 |
# les données ou qu'aucun événement correspondant n'est trouvé. |
198 |
self.app.post('/get_plugin_value', {
|
|
198 |
self.app.post('/plugin_json', {
|
|
199 | 199 |
'idcorrevent': idcorrevent, |
200 | 200 |
'plugin_name': 'details', |
201 | 201 |
}, extra_environ={'REMOTE_USER': 'no_access'}, |
... | ... | |
208 | 208 |
# Le contrôleur renvoie une erreur 404 (HTTPNotFound) |
209 | 209 |
# lorsque l'utilisateur n'a pas les permissions nécessaires sur |
210 | 210 |
# les données ou qu'aucun événement correspondant n'est trouvé. |
211 |
self.app.post('/get_plugin_value', {
|
|
211 |
self.app.post('/plugin_json', {
|
|
212 | 212 |
'idcorrevent': idcorrevent, |
213 | 213 |
'plugin_name': 'details', |
214 | 214 |
}, extra_environ={'REMOTE_USER': 'no_access'}, |
... | ... | |
220 | 220 |
|
221 | 221 |
# Le contrôleur renvoie une erreur 401 (HTTPUnauthorized) |
222 | 222 |
# lorsque l'utilisateur n'est pas authentifié. |
223 |
self.app.post('/get_plugin_value', {
|
|
223 |
self.app.post('/plugin_json', {
|
|
224 | 224 |
'idcorrevent': idcorrevent, |
225 | 225 |
'plugin_name': 'details', |
226 | 226 |
}, status=401) |
... | ... | |
231 | 231 |
|
232 | 232 |
# Le contrôleur renvoie une erreur 401 (HTTPUnauthorized) |
233 | 233 |
# lorsque l'utilisateur n'est pas authentifié. |
234 |
self.app.post('/get_plugin_value', {
|
|
234 |
self.app.post('/plugin_json', {
|
|
235 | 235 |
'idcorrevent': idcorrevent, |
236 | 236 |
'plugin_name': 'details', |
237 | 237 |
}, status=401) |
vigiboard/tests/functional/plugins/test_plugin_hls.py | ||
---|---|---|
31 | 31 |
|
32 | 32 |
# On crée un hôte de test. |
33 | 33 |
host = Host( |
34 |
name = u'host',
|
|
34 |
name = u'host', |
|
35 | 35 |
checkhostcmd = u'halt', |
36 | 36 |
snmpcommunity = u'public', |
37 | 37 |
hosttpl = u'/dev/null', |
... | ... | |
57 | 57 |
|
58 | 58 |
# On ajoute un évènement corrélé causé par cet évènement 'brut'. |
59 | 59 |
aggregate = CorrEvent( |
60 |
idcause = event1.idevent,
|
|
60 |
idcause = event1.idevent, |
|
61 | 61 |
timestamp_active = datetime.now(), |
62 | 62 |
priority = 1, |
63 | 63 |
status = u'None') |
64 | 64 |
aggregate.events.append(event1) |
65 | 65 |
DBSession.add(aggregate) |
66 | 66 |
DBSession.flush() |
67 |
|
|
67 |
|
|
68 | 68 |
transaction.commit() |
69 | 69 |
return aggregate |
70 | 70 |
|
71 | 71 |
def add_paths(path_number, path_length, idsupitem): |
72 |
"""
|
|
72 |
""" |
|
73 | 73 |
Ajoute path_number chemins de services de haut niveau impactés |
74 | 74 |
dans la base de donnée. Leur longeur sera égale à path_length. |
75 | 75 |
La 3ème valeur passée en paramètre est l'id du supitem impactant. |
76 |
|
|
77 |
path_number * path_length services de
|
|
76 |
|
|
77 |
path_number * path_length services de |
|
78 | 78 |
haut niveau sont créés dans l'opération. |
79 | 79 |
""" |
80 | 80 |
|
... | ... | |
89 | 89 |
|
90 | 90 |
# Création des chemins de services de haut niveau impactés. |
91 | 91 |
for j in range(path_number): |
92 |
|
|
92 |
|
|
93 | 93 |
# On crée le chemin en lui-même |
94 | 94 |
path = ImpactedPath(idsupitem = idsupitem) |
95 | 95 |
DBSession.add(path) |
96 | 96 |
DBSession.flush() |
97 |
|
|
97 |
|
|
98 | 98 |
# Pour chaque étage du chemin, |
99 | 99 |
for i in range(path_length): |
100 | 100 |
# on ajoute un service de haut niveau dans la BDD, |
101 | 101 |
hls = HighLevelService( |
102 |
servicename = u'HLS' + str(j + 1) + str(i + 1),
|
|
102 |
servicename = u'HLS' + str(j + 1) + str(i + 1), |
|
103 | 103 |
**hls_template) |
104 | 104 |
DBSession.add(hls) |
105 |
# et on ajoute un étage au chemin contenant ce service.
|
|
105 |
# et on ajoute un étage au chemin contenant ce service. |
|
106 | 106 |
DBSession.add( |
107 | 107 |
ImpactedHLS( |
108 | 108 |
path = path, |
109 | 109 |
hls = hls, |
110 | 110 |
distance = i + 1, |
111 | 111 |
)) |
112 |
|
|
112 |
|
|
113 | 113 |
DBSession.flush() |
114 | 114 |
transaction.commit() |
115 | 115 |
|
116 | 116 |
|
117 | 117 |
class TestHLSPlugin(TestController): |
118 | 118 |
""" |
119 |
Classe de test du contrôleur listant les services
|
|
119 |
Classe de test du contrôleur listant les services |
|
120 | 120 |
de haut niveau impactés par un évènement corrélé. |
121 | 121 |
""" |
122 | 122 |
def setUp(self): |
... | ... | |
137 | 137 |
DBSession.add(usergroup) |
138 | 138 |
DBSession.flush() |
139 | 139 |
|
140 |
user = User( |
|
141 |
user_name=u'no_access', |
|
142 |
fullname=u'', |
|
143 |
email=u'user.has.no@access', |
|
144 |
) |
|
145 |
usergroup = UserGroup( |
|
146 |
group_name=u'users_without_access', |
|
147 |
) |
|
148 |
usergroup.permissions.append(perm) |
|
149 |
user.usergroups.append(usergroup) |
|
150 |
DBSession.add(user) |
|
151 |
DBSession.add(usergroup) |
|
152 |
DBSession.flush() |
|
153 |
|
|
154 | 140 |
self.aggregate = populate_DB() |
155 | 141 |
|
156 | 142 |
def test_no_impacted_hls(self): |
157 | 143 |
""" |
158 |
Retour du plugin HLS pour 0 HLS impacté
|
|
159 |
Teste la valeur de retour du plugin lorsque
|
|
144 |
Données affichée par le plugin HLS pour 0 HLS impacté
|
|
145 |
Teste les données affichées par le plugin lorsque
|
|
160 | 146 |
aucun service de haut niveau n'est impacté. |
161 | 147 |
""" |
162 |
|
|
148 |
|
|
163 | 149 |
# On peuple la base de données avant le test. |
164 | 150 |
DBSession.add(self.aggregate) |
165 | 151 |
add_paths(0, 0, self.aggregate.events[0].idsupitem) |
166 | 152 |
DBSession.add(self.aggregate) |
167 |
|
|
168 |
### 1er cas : l'utilisateur n'est pas connecté. |
|
169 |
# On vérifie que le plugin retourne bien une erreur 401. |
|
170 |
resp = self.app.post( |
|
171 |
'/get_plugin_value', |
|
172 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
173 |
"plugin_name" : "hls"}, |
|
174 |
status = 401,) |
|
175 |
|
|
176 |
### 2ème cas : l'utilisateur n'a pas les |
|
177 |
### droits sur l'hôte ayant causé le correvent. |
|
178 |
# On vérifie que le plugin retourne bien une erreur 404. |
|
179 |
resp = self.app.post( |
|
180 |
'/get_plugin_value', |
|
181 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
182 |
"plugin_name" : "hls"}, |
|
183 |
status = 404, |
|
184 |
extra_environ={'REMOTE_USER': 'no_access'}) |
|
185 |
|
|
186 |
### 3ème cas : l'utilisateur a cette fois les droits. |
|
153 |
|
|
154 |
# On accède à la page principale de VigiBoard |
|
187 | 155 |
resp = self.app.post( |
188 |
'/get_plugin_value', |
|
189 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
190 |
"plugin_name" : "hls"}, |
|
191 |
extra_environ={'REMOTE_USER': 'access'}) |
|
192 |
# On vérifie que le plugin ne retourne toujours rien. |
|
193 |
assert_equal(resp.json, {"services": []}) |
|
194 |
|
|
156 |
'/', extra_environ={'REMOTE_USER': 'access'}) |
|
157 |
|
|
158 |
# On s'assure que la colonne des HLS |
|
159 |
# impactés est vide pour notre évènement. |
|
160 |
plugin_data = resp.lxml.xpath('//table[@class="vigitable"]' |
|
161 |
'/tbody/tr/td[@class="plugin_hls"]/text()') |
|
162 |
assert_equal(plugin_data[0].strip(), "") |
|
163 |
|
|
195 | 164 |
def test_1_impacted_hls_path(self): |
196 | 165 |
""" |
197 |
Retour du plugin HLS pour 1 chemin impacté
|
|
198 |
Teste la valeur de retour du plugin lorsqu'un
|
|
199 |
chemin de services de haut niveau est impacté. |
|
166 |
Données affichée par le plugin HLS pour 1 chemin impacté
|
|
167 |
Teste les données affichées par le plugin lorsque
|
|
168 |
1 chemin de services de haut niveau est impacté.
|
|
200 | 169 |
""" |
201 |
|
|
170 |
|
|
202 | 171 |
# On peuple la base de données avant le test. |
203 | 172 |
DBSession.add(self.aggregate) |
204 | 173 |
add_paths(1, 2, self.aggregate.events[0].idsupitem) |
205 | 174 |
DBSession.add(self.aggregate) |
206 |
|
|
207 |
### 1er cas : l'utilisateur n'est pas connecté. |
|
208 |
# On vérifie que le plugin retourne bien une erreur 401. |
|
209 |
resp = self.app.post( |
|
210 |
'/get_plugin_value', |
|
211 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
212 |
"plugin_name" : "hls"}, |
|
213 |
status = 401,) |
|
214 |
|
|
215 |
### 2ème cas : l'utilisateur n'a pas les droits |
|
216 |
### sur l'hôte ayant causé le correvent, on doit |
|
217 |
### obtenir une erreur 404 (pas d'événement trouvé |
|
218 |
### avec les informations liées à cet utilisateur). |
|
219 |
resp = self.app.post( |
|
220 |
'/get_plugin_value', |
|
221 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
222 |
"plugin_name" : "hls"}, |
|
223 |
status = 404, |
|
224 |
extra_environ={'REMOTE_USER': 'no_access'}) |
|
225 |
|
|
226 |
### 3ème cas : l'utilisateur a cette fois les droits. |
|
175 |
|
|
176 |
# On accède à la page principale de VigiBoard |
|
227 | 177 |
resp = self.app.post( |
228 |
'/get_plugin_value', |
|
229 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
230 |
"plugin_name" : "hls"}, |
|
231 |
extra_environ={'REMOTE_USER': 'access'}) |
|
232 |
# On vérifie que le plugin retourne bien les 2 HLS impactés. |
|
233 |
assert_equal(resp.json, {"services": ['HLS12']}) |
|
234 |
|
|
178 |
'/', extra_environ={'REMOTE_USER': 'access'}) |
|
179 |
|
|
180 |
# On s'assure que la colonne des HLS impactés contient |
|
181 |
# bien le nom de notre HLS de plus haut niveau impacté. |
|
182 |
plugin_data = resp.lxml.xpath('//table[@class="vigitable"]' |
|
183 |
'/tbody/tr/td[@class="plugin_hls"]/text()') |
|
184 |
assert_equal(plugin_data[0].strip(), "HLS12") |
|
185 |
|
|
235 | 186 |
def test_2_impacted_hls_path(self): |
236 | 187 |
""" |
237 |
Retour du plugin HLS pour 2 chemins impactés
|
|
238 |
Teste la valeur de retour du plugin lorsque deux
|
|
239 |
chemins de services de haut niveau sont impactés. |
|
188 |
Données affichée par le plugin HLS pour 2 chemins impactés
|
|
189 |
Teste les données affichées par le plugin lorsque
|
|
190 |
2 chemins de services de haut niveau sont impactés.
|
|
240 | 191 |
""" |
241 |
|
|
192 |
|
|
242 | 193 |
# On peuple la base de données avant le test. |
243 | 194 |
DBSession.add(self.aggregate) |
244 | 195 |
add_paths(2, 2, self.aggregate.events[0].idsupitem) |
245 | 196 |
DBSession.add(self.aggregate) |
246 |
|
|
247 |
### 1er cas : l'utilisateur n'est pas connecté. |
|
248 |
# On vérifie que le plugin retourne bien une erreur 401. |
|
249 |
resp = self.app.post( |
|
250 |
'/get_plugin_value', |
|
251 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
252 |
"plugin_name" : "hls"}, |
|
253 |
status = 401,) |
|
254 |
|
|
255 |
### 2ème cas : l'utilisateur n'a pas les |
|
256 |
### droits sur l'hôte ayant causé le correvent. |
|
257 |
resp = self.app.post( |
|
258 |
'/get_plugin_value', |
|
259 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
260 |
"plugin_name" : "hls"}, |
|
261 |
status = 404, |
|
262 |
extra_environ={'REMOTE_USER': 'no_access'}) |
|
263 |
|
|
264 |
### 3ème cas : l'utilisateur a cette fois les droits. |
|
197 |
|
|
198 |
# On accède à la page principale de VigiBoard |
|
265 | 199 |
resp = self.app.post( |
266 |
'/get_plugin_value', |
|
267 |
{"idcorrevent" : str(self.aggregate.idcorrevent), |
|
268 |
"plugin_name" : "hls"}, |
|
269 |
extra_environ={'REMOTE_USER': 'access'}) |
|
270 |
# On vérifie que le plugin retourne bien les 4 HLS impactés. |
|
271 |
assert_equal(resp.json, {"services": ['HLS12', 'HLS22']}) |
|
200 |
'/', extra_environ={'REMOTE_USER': 'access'}) |
|
201 |
|
|
202 |
# On s'assure que la colonne des HLS contient bien |
|
203 |
# le nombre de HLS de plus haut niveau impactés, |
|
204 |
plugin_data = resp.lxml.xpath('//table[@class="vigitable"]' |
|
205 |
'/tbody/tr/td[@class="plugin_hls"]/a/text()') |
|
206 |
assert_equal(plugin_data[0].strip(), "2") |
|
272 | 207 |
|
Also available in: Unified diff