Revision dc005588
Liens vers les cartes dans VigiBoard (#959).
Ajoute des liens vers les cartes sur lesquelles l'hôte concerné par un
événement apparaît dans le dialogue de détail d'un l'événement corrélé.
L'URL de base de VigiMap doit être renseignée dans le fichier de
configuration de VigiBoard pour que ceci fonctionne. La configuration de
l'URL se fait grâce à l'option de configuration "interfaces.vigimap" (le
nom est le même que celui attendu par VigiAdmin).
"max_maps" avec 2 valeurs particulières :
- -1 inhibe toute limite (ie. affiche toutes les cartes)
- 0 désactive la fonctionnalité (ie. n'affiche aucune carte, ni même la
partie réservée à l'affichage des liens dans la boîte de dialogue)
Si le nombre de cartes disponibles est supérieur à la limite définie et
que le mécanisme d'affiche des liens est activé, un message avertit en
plus l'utilisateur.
Ajoute des tests sur cette nouvelle fonctionnalité.
De plus, le code !JavaScript du module "details" a été externalisé afin
de faciliter la lecture du fichier .html du module.
Enfin, le comportement d'ouverture des liens (ex: dans l'onglet courant
ou dans un nouvel onglet) est configurable grâce à l'option
"links_target" (il s'agit du même nom d'option que dans VigiAdmin).
Change-Id: I0d1b73fc4e9e7caf36e10a87bc3e0ae3d8972d88
Refs: #959.
Reviewed-on: https://vigilo-dev.si.c-s.fr/review/690
Tested-by: Build system <qa@vigilo-dev.si.c-s.fr>
Reviewed-by: Aurelien BOMPARD <aurelien.bompard@c-s.fr>
Makefile | ||
---|---|---|
8 | 8 |
|
9 | 9 |
include buildenv/Makefile.common.python |
10 | 10 |
MODULE := $(NAME) |
11 |
EPYDOC_PARSE := vigiboard\.(widgets|controllers) |
|
11 |
EPYDOC_PARSE := vigiboard\.(widgets|controllers|tests)
|
|
12 | 12 |
|
13 | 13 |
deployment/%: deployment/%.in |
14 | 14 |
sed -e 's,@SYSCONFDIR@,$(SYSCONFDIR),g' \ |
deployment/settings.ini.in | ||
---|---|---|
110 | 110 |
; (état d'acquittement et priorité ITIL). |
111 | 111 |
state_first = True |
112 | 112 |
|
113 |
; Adresse des autres interfaces de Vigilo. |
|
114 |
; Il peut s'agir de chemins absolus sur le même serveur (ex: /../vigimap/) |
|
115 |
; ou d'URL complètes (http://other-server.example.com/vigilo/vigimap/). |
|
116 |
; Si les liens sont donnés sous forme absolue, ils sont en fait interprétés |
|
117 |
; comme des liens relatifs par rapport à VigiBoard. |
|
118 |
interfaces.vigimap = /../vigimap/ |
|
119 |
|
|
120 |
; Cible pour l'ouverture des liens vers les autres interfaces. |
|
121 |
; Les valeurs possibles sont: |
|
122 |
; "_self" : ouvre la nouvelle page dans le cadre courant. |
|
123 |
; "_top" : ouvre la nouvelle page à la place de la page courante. |
|
124 |
; "_blank" : ouvre la nouvelle page dans une nouvelle fenêtre |
|
125 |
; ou dans un nouvel onglet. |
|
126 |
; "_parent" : ouvre la nouvelle page dans le cadre parent. |
|
127 |
; <autre> : ouvre la nouvelle page dans le cadre nommé <autre>. |
|
128 |
; La valeur par défaut est "_blank". |
|
129 |
;links_target = _blank |
|
130 |
|
|
131 |
; Indique le nombre maximum de cartes qui peuvent être affichées |
|
132 |
; dans le module de détail de l'événement corrélé. |
|
133 |
; La valeur -1 supprime toute limite, tandis que la valeur 0 |
|
134 |
; supprime l'affichage des liens vers les cartes. |
|
135 |
max_maps = -1 |
|
136 |
|
|
113 | 137 |
; |
114 | 138 |
; 4 - Configuration du proxy Nagios. |
115 | 139 |
; |
development.ini | ||
---|---|---|
26 | 26 |
password_hashing_function=md5 |
27 | 27 |
lang=fr |
28 | 28 |
help_link=http://foo.bar/help |
29 |
interfaces.vigimap=http://localhost:8080/ |
|
30 |
max_maps = -1 |
|
29 | 31 |
|
30 | 32 |
; Délai de rafraîchissement automatique (en secondes). |
31 | 33 |
refresh_delay=30 |
test.ini | ||
---|---|---|
24 | 24 |
[app:main_without_authn] |
25 | 25 |
use = main |
26 | 26 |
skip_authentication = True |
27 |
|
|
28 |
[app:limited_maps] |
|
29 |
use = main_without_authn |
|
30 |
max_maps = 1 |
|
31 |
|
|
32 |
[app:disabled_maps] |
|
33 |
use = main_without_authn |
|
34 |
max_maps = 0 |
|
35 |
|
|
36 |
[app:unlimited_maps] |
|
37 |
use = main_without_authn |
|
38 |
max_maps = -2 |
vigiboard/controllers/plugins/details.py | ||
---|---|---|
25 | 25 |
""" |
26 | 26 |
|
27 | 27 |
import urllib |
28 |
from tg import config, url |
|
28 |
from tg import config, url, request
|
|
29 | 29 |
from sqlalchemy.sql.expression import null as expr_null, union_all |
30 | 30 |
|
31 |
from repoze.what.predicates import has_permission, in_group |
|
32 |
from vigilo.turbogears.helpers import get_current_user |
|
33 |
|
|
31 | 34 |
from vigilo.models.session import DBSession |
32 |
from vigilo.models.tables import Event, \ |
|
33 |
CorrEvent, Host, LowLevelService, StateName |
|
35 |
from vigilo.models.tables import Event, CorrEvent, Host, LowLevelService, \ |
|
36 |
StateName, Map, MapNode, MapNodeHost, MapGroup |
|
37 |
from vigilo.models.tables.secondary_tables import MAP_GROUP_TABLE |
|
34 | 38 |
|
35 | 39 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
36 | 40 |
|
... | ... | |
52 | 56 |
# Obtention de données sur l'événement et sur son historique |
53 | 57 |
host_query = DBSession.query( |
54 | 58 |
Host.idhost.label("idsupitem"), |
59 |
Host.idhost.label("idhost"), |
|
55 | 60 |
Host.name.label("host"), |
56 | 61 |
expr_null().label("service"), |
57 | 62 |
) |
58 | 63 |
lls_query = DBSession.query( |
59 | 64 |
LowLevelService.idservice.label("idsupitem"), |
65 |
Host.idhost.label("idhost"), |
|
60 | 66 |
Host.name.label("host"), |
61 | 67 |
LowLevelService.servicename.label("service"), |
62 | 68 |
).join( |
... | ... | |
66 | 72 |
event = DBSession.query( |
67 | 73 |
CorrEvent.idcorrevent, |
68 | 74 |
CorrEvent.idcause, |
75 |
supitems.c.idhost, |
|
69 | 76 |
supitems.c.host, |
70 | 77 |
supitems.c.service, |
71 | 78 |
Event.message, |
... | ... | |
78 | 85 |
).filter(CorrEvent.idcorrevent == idcorrevent |
79 | 86 |
).first() |
80 | 87 |
|
88 |
# On détermine les cartes auxquelles cet utilisateur a accès. |
|
89 |
user_maps = {} |
|
90 |
max_maps = int(config['max_maps']) |
|
91 |
is_manager = in_group('managers').is_met(request.environ) |
|
92 |
if max_maps != 0 and (is_manager or |
|
93 |
has_permission('vigimap-access').is_met(request.environ)): |
|
94 |
items = DBSession.query( |
|
95 |
Map.idmap, |
|
96 |
Map.title, |
|
97 |
).distinct( |
|
98 |
).join( |
|
99 |
(MAP_GROUP_TABLE, MAP_GROUP_TABLE.c.idmap == Map.idmap), |
|
100 |
(MapGroup, MapGroup.idgroup == MAP_GROUP_TABLE.c.idgroup), |
|
101 |
(MapNodeHost, MapNodeHost.idmap == Map.idmap), |
|
102 |
).order_by(Map.title.asc() |
|
103 |
).filter(MapNodeHost.idhost == event.idhost) |
|
104 |
|
|
105 |
if not is_manager: |
|
106 |
mapgroups = get_current_user().mapgroups(only_direct=True) |
|
107 |
# pylint: disable-msg=E1103 |
|
108 |
items = items.filter(MapGroup.idgroup.in_(mapgroups)) |
|
109 |
|
|
110 |
# La valeur -1 supprime la limite. |
|
111 |
if max_maps > 0: |
|
112 |
# On limite au nombre maximum de cartes demandés + 1. |
|
113 |
# Un message sera affiché s'il y a effectivement plus |
|
114 |
# de cartes que la limite configurée. |
|
115 |
items = items.limit(max_maps + 1) |
|
116 |
|
|
117 |
user_maps = dict([(m.idmap, m.title) for m in items.all()]) |
|
118 |
|
|
81 | 119 |
context = { |
82 | 120 |
'idcorrevent': idcorrevent, |
83 | 121 |
'host': event.host, |
84 | 122 |
'service': event.service, |
85 | 123 |
'message': event.message, |
124 |
'maps': user_maps, |
|
86 | 125 |
} |
87 | 126 |
|
88 | 127 |
eventdetails = {} |
... | ... | |
122 | 161 |
host = event.host, |
123 | 162 |
service = event.service, |
124 | 163 |
eventdetails = eventdetails, |
164 |
maps = user_maps, |
|
125 | 165 |
idcause = event.idcause, |
126 | 166 |
) |
vigiboard/i18n/de/LC_MESSAGES/vigiboard.po | ||
---|---|---|
8 | 8 |
"Project-Id-Version: vigiboard 2.0.0\n" |
9 | 9 |
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" |
10 | 10 |
"POT-Creation-Date: 2010-11-19 10:22+0100\n" |
11 |
"PO-Revision-Date: 2012-01-06 11:27+0100\n"
|
|
11 |
"PO-Revision-Date: 2012-04-27 10:57+0200\n"
|
|
12 | 12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
13 | 13 |
"Language-Team: de_DE <LL@li.org>\n" |
14 | 14 |
"Plural-Forms: nplurals=2; plural=(n != 1)\n" |
... | ... | |
117 | 117 |
"\"%(previous)s\" to \"%(new)s\" on event #%(idevent)d" |
118 | 118 |
msgstr "" |
119 | 119 |
|
120 |
#: vigiboard/controllers/root.py:650
|
|
120 |
#: vigiboard/controllers/root.py:651
|
|
121 | 121 |
#, python-format |
122 | 122 |
msgid "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d" |
123 | 123 |
msgstr "" |
124 | 124 |
|
125 |
#: vigiboard/controllers/root.py:666
|
|
125 |
#: vigiboard/controllers/root.py:667
|
|
126 | 126 |
msgid "Forced" |
127 | 127 |
msgstr "" |
128 | 128 |
|
129 |
#: vigiboard/controllers/root.py:684
|
|
129 |
#: vigiboard/controllers/root.py:686
|
|
130 | 130 |
#, python-format |
131 | 131 |
msgid "" |
132 | 132 |
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" " |
133 | 133 |
"to \"%(new)s\" on event #%(idevent)d" |
134 | 134 |
msgstr "" |
135 | 135 |
|
136 |
#: vigiboard/controllers/root.py:696
|
|
136 |
#: vigiboard/controllers/root.py:698
|
|
137 | 137 |
msgid "Updated successfully" |
138 | 138 |
msgstr "Erfolgreich aktualisiert" |
139 | 139 |
|
140 |
#: vigiboard/controllers/root.py:721
|
|
140 |
#: vigiboard/controllers/root.py:723
|
|
141 | 141 |
#, fuzzy, python-format |
142 | 142 |
msgid "No such plugin '%s'" |
143 | 143 |
msgstr "Plug-In \"%s\" nicht vorhanden" |
144 | 144 |
|
145 |
#: vigiboard/controllers/root.py:764
|
|
145 |
#: vigiboard/controllers/root.py:766
|
|
146 | 146 |
msgid "No such incident or insufficient permissions" |
147 | 147 |
msgstr "Ereignis nicht vorhanden oder unzureichende Berechtigungen" |
148 | 148 |
|
149 |
#: vigiboard/controllers/root.py:876
|
|
149 |
#: vigiboard/controllers/root.py:878
|
|
150 | 150 |
#, python-format |
151 | 151 |
msgid "Next %(limit)s" |
152 | 152 |
msgstr "" |
vigiboard/i18n/en/LC_MESSAGES/vigiboard.po | ||
---|---|---|
6 | 6 |
# |
7 | 7 |
msgid "" |
8 | 8 |
msgstr "" |
9 |
"Project-Id-Version: vigilo-vigiboard 2.0.11\n"
|
|
9 |
"Project-Id-Version: vigilo-vigiboard 2.0.16\n"
|
|
10 | 10 |
"Report-Msgid-Bugs-To: contact@projet-vigilo.org\n" |
11 |
"POT-Creation-Date: 2012-01-06 11:27+0100\n"
|
|
12 |
"PO-Revision-Date: 2012-01-06 11:27+0100\n"
|
|
11 |
"POT-Creation-Date: 2012-04-27 10:57+0200\n"
|
|
12 |
"PO-Revision-Date: 2012-04-27 10:57+0200\n"
|
|
13 | 13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
14 | 14 |
"Language-Team: en <LL@li.org>\n" |
15 | 15 |
"Plural-Forms: nplurals=2; plural=(n != 1)\n" |
... | ... | |
117 | 117 |
"User \"%(user)s\" (%(address)s) changed the trouble ticket from " |
118 | 118 |
"\"%(previous)s\" to \"%(new)s\" on event #%(idevent)d" |
119 | 119 |
|
120 |
#: vigiboard/controllers/root.py:650
|
|
120 |
#: vigiboard/controllers/root.py:651
|
|
121 | 121 |
#, python-format |
122 | 122 |
msgid "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d" |
123 | 123 |
msgstr "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d" |
124 | 124 |
|
125 |
#: vigiboard/controllers/root.py:666
|
|
125 |
#: vigiboard/controllers/root.py:667
|
|
126 | 126 |
msgid "Forced" |
127 | 127 |
msgstr "Forced" |
128 | 128 |
|
129 |
#: vigiboard/controllers/root.py:684
|
|
129 |
#: vigiboard/controllers/root.py:686
|
|
130 | 130 |
#, python-format |
131 | 131 |
msgid "" |
132 | 132 |
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" " |
... | ... | |
135 | 135 |
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" " |
136 | 136 |
"to \"%(new)s\" on event #%(idevent)d" |
137 | 137 |
|
138 |
#: vigiboard/controllers/root.py:696
|
|
138 |
#: vigiboard/controllers/root.py:698
|
|
139 | 139 |
msgid "Updated successfully" |
140 | 140 |
msgstr "Updated successfully" |
141 | 141 |
|
142 |
#: vigiboard/controllers/root.py:721
|
|
142 |
#: vigiboard/controllers/root.py:723
|
|
143 | 143 |
#, python-format |
144 | 144 |
msgid "No such plugin '%s'" |
145 | 145 |
msgstr "No such plugin '%s'" |
146 | 146 |
|
147 |
#: vigiboard/controllers/root.py:764
|
|
147 |
#: vigiboard/controllers/root.py:766
|
|
148 | 148 |
msgid "No such incident or insufficient permissions" |
149 | 149 |
msgstr "No such incident or insufficient permissions" |
150 | 150 |
|
151 |
#: vigiboard/controllers/root.py:876
|
|
151 |
#: vigiboard/controllers/root.py:878
|
|
152 | 152 |
#, python-format |
153 | 153 |
msgid "Next %(limit)s" |
154 | 154 |
msgstr "Next %(limit)s" |
vigiboard/i18n/fr/LC_MESSAGES/vigiboard.po | ||
---|---|---|
8 | 8 |
"Project-Id-Version: vigiboard 0.1\n" |
9 | 9 |
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" |
10 | 10 |
"POT-Creation-Date: 2009-07-06 11:19+0200\n" |
11 |
"PO-Revision-Date: 2012-01-06 11:27+0100\n"
|
|
11 |
"PO-Revision-Date: 2012-04-27 10:57+0200\n"
|
|
12 | 12 |
"Last-Translator: Thomas ANDREJAK <thomas.andrejak@c-s.fr>\n" |
13 | 13 |
"Language-Team: fr_FR <LL@li.org>\n" |
14 | 14 |
"Plural-Forms: nplurals=2; plural=(n > 1)\n" |
... | ... | |
116 | 116 |
"L'utilisateur \"%(user)s\" (%(address)s) a changé le ticket d'incident de" |
117 | 117 |
" l'événement n°%(idevent)d de \"%(previous)s\" vers \"%(new)s\"" |
118 | 118 |
|
119 |
#: vigiboard/controllers/root.py:650
|
|
119 |
#: vigiboard/controllers/root.py:651
|
|
120 | 120 |
#, python-format |
121 | 121 |
msgid "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d" |
122 | 122 |
msgstr "" |
123 | 123 |
"L'utilisateur \"%(user)s\" (%(address)s) a forcé la fermeture de " |
124 | 124 |
"l'événement #%(idevent)d" |
125 | 125 |
|
126 |
#: vigiboard/controllers/root.py:666
|
|
126 |
#: vigiboard/controllers/root.py:667
|
|
127 | 127 |
msgid "Forced" |
128 | 128 |
msgstr "Forcé" |
129 | 129 |
|
130 |
#: vigiboard/controllers/root.py:684
|
|
130 |
#: vigiboard/controllers/root.py:686
|
|
131 | 131 |
#, python-format |
132 | 132 |
msgid "" |
133 | 133 |
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" " |
... | ... | |
136 | 136 |
"L'utilisateur \"%(user)s\" (%(address)s) a changé l'état de l'événement " |
137 | 137 |
"n°%(idevent)d de \"%(previous)s\" vers \"%(new)s\"" |
138 | 138 |
|
139 |
#: vigiboard/controllers/root.py:696
|
|
139 |
#: vigiboard/controllers/root.py:698
|
|
140 | 140 |
msgid "Updated successfully" |
141 | 141 |
msgstr "Mise à jour réussie" |
142 | 142 |
|
143 |
#: vigiboard/controllers/root.py:721
|
|
143 |
#: vigiboard/controllers/root.py:723
|
|
144 | 144 |
#, python-format |
145 | 145 |
msgid "No such plugin '%s'" |
146 | 146 |
msgstr "Module introuvable \"%s\"" |
147 | 147 |
|
148 |
#: vigiboard/controllers/root.py:764
|
|
148 |
#: vigiboard/controllers/root.py:766
|
|
149 | 149 |
msgid "No such incident or insufficient permissions" |
150 | 150 |
msgstr "Aucun incident correspondant ou permissions insuffisantes" |
151 | 151 |
|
152 |
#: vigiboard/controllers/root.py:876
|
|
152 |
#: vigiboard/controllers/root.py:878
|
|
153 | 153 |
#, python-format |
154 | 154 |
msgid "Next %(limit)s" |
155 | 155 |
msgstr "%(limit)s suivants" |
vigiboard/i18n/vigiboard.pot | ||
---|---|---|
7 | 7 |
#, fuzzy |
8 | 8 |
msgid "" |
9 | 9 |
msgstr "" |
10 |
"Project-Id-Version: vigilo-vigiboard 2.0.11\n"
|
|
10 |
"Project-Id-Version: vigilo-vigiboard 2.0.16\n"
|
|
11 | 11 |
"Report-Msgid-Bugs-To: contact@projet-vigilo.org\n" |
12 |
"POT-Creation-Date: 2012-01-06 11:27+0100\n"
|
|
12 |
"POT-Creation-Date: 2012-04-27 10:57+0200\n"
|
|
13 | 13 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
14 | 14 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
15 | 15 |
"Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | |
113 | 113 |
"\"%(previous)s\" to \"%(new)s\" on event #%(idevent)d" |
114 | 114 |
msgstr "" |
115 | 115 |
|
116 |
#: vigiboard/controllers/root.py:650
|
|
116 |
#: vigiboard/controllers/root.py:651
|
|
117 | 117 |
#, python-format |
118 | 118 |
msgid "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d" |
119 | 119 |
msgstr "" |
120 | 120 |
|
121 |
#: vigiboard/controllers/root.py:666
|
|
121 |
#: vigiboard/controllers/root.py:667
|
|
122 | 122 |
msgid "Forced" |
123 | 123 |
msgstr "" |
124 | 124 |
|
125 |
#: vigiboard/controllers/root.py:684
|
|
125 |
#: vigiboard/controllers/root.py:686
|
|
126 | 126 |
#, python-format |
127 | 127 |
msgid "" |
128 | 128 |
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" to " |
129 | 129 |
"\"%(new)s\" on event #%(idevent)d" |
130 | 130 |
msgstr "" |
131 | 131 |
|
132 |
#: vigiboard/controllers/root.py:696
|
|
132 |
#: vigiboard/controllers/root.py:698
|
|
133 | 133 |
msgid "Updated successfully" |
134 | 134 |
msgstr "" |
135 | 135 |
|
136 |
#: vigiboard/controllers/root.py:721
|
|
136 |
#: vigiboard/controllers/root.py:723
|
|
137 | 137 |
#, python-format |
138 | 138 |
msgid "No such plugin '%s'" |
139 | 139 |
msgstr "" |
140 | 140 |
|
141 |
#: vigiboard/controllers/root.py:764
|
|
141 |
#: vigiboard/controllers/root.py:766
|
|
142 | 142 |
msgid "No such incident or insufficient permissions" |
143 | 143 |
msgstr "" |
144 | 144 |
|
145 |
#: vigiboard/controllers/root.py:876
|
|
145 |
#: vigiboard/controllers/root.py:878
|
|
146 | 146 |
#, python-format |
147 | 147 |
msgid "Next %(limit)s" |
148 | 148 |
msgstr "" |
vigiboard/tests/functional/plugins/test_details_plugin.py | ||
---|---|---|
115 | 115 |
"peak_state": "WARNING", |
116 | 116 |
"current_state": "WARNING", |
117 | 117 |
"host": "bar", |
118 |
"initial_state": "WARNING" |
|
118 |
"initial_state": "WARNING", |
|
119 |
"maps": {}, |
|
119 | 120 |
}) |
120 | 121 |
|
121 | 122 |
def test_details_plugin_LLS_alert_when_manager(self): |
... | ... | |
140 | 141 |
"peak_state": "WARNING", |
141 | 142 |
"current_state": "WARNING", |
142 | 143 |
"host": "bar", |
143 |
"initial_state": "WARNING" |
|
144 |
"initial_state": "WARNING", |
|
145 |
"maps": {}, |
|
144 | 146 |
}) |
145 | 147 |
|
146 | 148 |
def test_details_plugin_host_alert_when_allowed(self): |
... | ... | |
165 | 167 |
"peak_state": "WARNING", |
166 | 168 |
"current_state": "WARNING", |
167 | 169 |
"host": "bar", |
168 |
"initial_state": "WARNING" |
|
170 |
"initial_state": "WARNING", |
|
171 |
"maps": {}, |
|
169 | 172 |
}) |
170 | 173 |
|
171 | 174 |
def test_details_plugin_host_alert_when_manager(self): |
... | ... | |
190 | 193 |
"peak_state": "WARNING", |
191 | 194 |
"current_state": "WARNING", |
192 | 195 |
"host": "bar", |
193 |
"initial_state": "WARNING" |
|
196 |
"initial_state": "WARNING", |
|
197 |
"maps": {}, |
|
194 | 198 |
}) |
195 | 199 |
|
196 | 200 |
def test_details_plugin_LLS_when_forbidden(self): |
vigiboard/tests/functional/plugins/test_details_plugin_maps.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# Copyright (C) 2006-2011 CS-SI |
|
3 |
# License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html> |
|
4 |
|
|
5 |
""" |
|
6 |
Teste la partie "Cartes" du formulaire contenant les détails |
|
7 |
pour un événement corrélé. |
|
8 |
""" |
|
9 |
from datetime import datetime |
|
10 |
import transaction |
|
11 |
|
|
12 |
from vigiboard.tests import TestController |
|
13 |
from vigilo.models.session import DBSession |
|
14 |
from vigilo.models.demo import functions |
|
15 |
from vigilo.models.tables import Permission, CorrEvent, Host, LowLevelService |
|
16 |
|
|
17 |
class TestDetailsPluginMapsHostLimited(TestController): |
|
18 |
""" |
|
19 |
Teste l'affichage des cartes dans le module de détails |
|
20 |
lorsqu'une limite à été réglée pour l'affichage. |
|
21 |
""" |
|
22 |
application_under_test = 'limited_maps' |
|
23 |
# Seules les 2 premières cartes doivent figurer. |
|
24 |
# La 1ère correspond à la limite, la 2 seconde permet |
|
25 |
# de détecter qu'il y avait plus de cartes que la limite. |
|
26 |
manager = {'1': 'M1', '2': 'M2'} |
|
27 |
# L'utilisateur avec droits étendus voit |
|
28 |
# la même chose que le manager (2 cartes). |
|
29 |
unrestricted = manager.copy() |
|
30 |
# L'utilisateur avec droits restreints ne voit |
|
31 |
# qu'une seule carte : "M2". |
|
32 |
restricted = {'2': 'M2'} |
|
33 |
supitem_class = Host |
|
34 |
|
|
35 |
def shortDescription(self, *args, **kwargs): |
|
36 |
"""Description courte du test en cours d'exécution.""" |
|
37 |
res = TestController.shortDescription(*args, **kwargs) |
|
38 |
return "%s (limited + host)" % (res, ) |
|
39 |
|
|
40 |
def setUp(self): |
|
41 |
"""Initialisation avant chaque test.""" |
|
42 |
super(TestDetailsPluginMapsHostLimited, self).setUp() |
|
43 |
# On fait manuellement ce que l'initialisation de VigiMap ferait |
|
44 |
# (car on est dans les tests de VigiBoard, pas ceux de VigiMap). |
|
45 |
root = functions.add_mapgroup(u'Root') |
|
46 |
DBSession.add(Permission(permission_name=u'vigimap-access')) |
|
47 |
|
|
48 |
print "Creation hote, service et cartes" |
|
49 |
host = functions.add_host(u'localhost éçà') |
|
50 |
functions.add_lowlevelservice(host, u'lls éçà') |
|
51 |
sig = functions.add_supitemgroup(u'supitemgroup éçà') |
|
52 |
functions.add_host2group(host, sig) |
|
53 |
mg = functions.add_mapgroup(u'éçà', root) |
|
54 |
m1 = functions.add_map(u'M1', root) |
|
55 |
# La seconde carte appartient à "/Root/éçà" |
|
56 |
# et permet de tester les accès indirects. |
|
57 |
m2 = functions.add_map(u'M2', mg) |
|
58 |
m3 = functions.add_map(u'M3', root) |
|
59 |
|
|
60 |
# On ajoute l'hôte 2 fois sur M1 pour vérifier |
|
61 |
# l'absense de doublons dans les liens. |
|
62 |
print "Preparation cartes" |
|
63 |
functions.add_node_host(host, 'h1', m1) |
|
64 |
functions.add_node_host(host, 'h2', m1) |
|
65 |
functions.add_node_host(host, 'h', m2) |
|
66 |
functions.add_node_host(host, 'h', m3) |
|
67 |
|
|
68 |
# Création de quelques utilisateurs. |
|
69 |
print "Creation des comptes utilisateurs et reglages permissions" |
|
70 |
functions.add_user(u'restricted', u're@strict.ed', |
|
71 |
u'restricted', u'restricted', |
|
72 |
u'restricted') |
|
73 |
functions.add_user(u'unrestricted', u'unre@strict.ed', |
|
74 |
u'unrestricted', u'unrestricted', |
|
75 |
u'unrestricted') |
|
76 |
functions.add_user(u'no_rights', u'no_r@igh.ts', |
|
77 |
u'no_rights', u'no_rights', |
|
78 |
u'no_rights') |
|
79 |
# Les 3 utilisateurs ont accès à VigiBoard. |
|
80 |
functions.add_usergroup_permission(u'no_rights', u'vigiboard-access') |
|
81 |
functions.add_usergroup_permission(u'restricted', u'vigiboard-access') |
|
82 |
functions.add_usergroup_permission(u'unrestricted', u'vigiboard-access') |
|
83 |
# Mais seuls "restricted" et "unrestricted" ont accès à VigiMap. |
|
84 |
functions.add_usergroup_permission(u'restricted', u'vigimap-access') |
|
85 |
functions.add_usergroup_permission(u'unrestricted', u'vigimap-access') |
|
86 |
# Ils voient tous les trois les événements dans VigiBoard... |
|
87 |
functions.add_supitemgrouppermission(sig, 'no_rights') |
|
88 |
functions.add_supitemgrouppermission(sig, 'restricted') |
|
89 |
functions.add_supitemgrouppermission(sig, 'unrestricted') |
|
90 |
# ... mais "restricted" ne peut voir que "M2" ... |
|
91 |
functions.add_MapGroupPermission(mg, 'restricted') |
|
92 |
# ... tandis que "unrestricted" voit les 3 cartes (par héritage). |
|
93 |
functions.add_MapGroupPermission(root, 'unrestricted') |
|
94 |
|
|
95 |
DBSession.flush() |
|
96 |
transaction.commit() |
|
97 |
|
|
98 |
def tearDown(self): |
|
99 |
"""Nettoyage après chaque test.""" |
|
100 |
transaction.abort() |
|
101 |
DBSession.expunge_all() |
|
102 |
super(TestDetailsPluginMapsHostLimited, self).tearDown() |
|
103 |
|
|
104 |
def _insert_dep(self): |
|
105 |
"""Insertion de l'événement corrélé de test.""" |
|
106 |
print "Insertion evenement correle" |
|
107 |
timestamp = datetime.now() |
|
108 |
supitem = DBSession.query(self.supitem_class).one() |
|
109 |
if isinstance(supitem, Host): |
|
110 |
event = functions.add_event(supitem, u'DOWN', u'', timestamp) |
|
111 |
else: # Sinon, il s'agit d'un LowLevelService. |
|
112 |
event = functions.add_event(supitem, u'CRITICAL', u'', timestamp) |
|
113 |
functions.add_correvent([event], timestamp=timestamp) |
|
114 |
DBSession.flush() |
|
115 |
transaction.commit() |
|
116 |
correvent = DBSession.query(CorrEvent.idcorrevent).one() |
|
117 |
return correvent.idcorrevent |
|
118 |
|
|
119 |
def test_maps_links_anonymous(self): |
|
120 |
"""Cartes dans dialogue détails en tant qu'anonyme.""" |
|
121 |
idcorrevent = self._insert_dep() |
|
122 |
# 401 : Unauthorized car l'utilisateur doit s'authentifier |
|
123 |
# pour pouvoir accéder à la boîte de dialogue. |
|
124 |
self.app.post('/plugin_json', { |
|
125 |
'idcorrevent': idcorrevent, |
|
126 |
'plugin_name': 'details', |
|
127 |
}, extra_environ={}, status=401) |
|
128 |
|
|
129 |
def test_maps_links_manager(self): |
|
130 |
"""Cartes dans dialogue détails en tant que manager.""" |
|
131 |
idcorrevent = self._insert_dep() |
|
132 |
response = self.app.post('/plugin_json', { |
|
133 |
'idcorrevent': idcorrevent, |
|
134 |
'plugin_name': 'details', |
|
135 |
}, extra_environ={'REMOTE_USER': 'manager'}) |
|
136 |
# Le manager a toujours accès à tout, la seule limite possible |
|
137 |
# est celle imposée par l'option "max_maps" dans la configuration. |
|
138 |
self.assertEquals(response.json['maps'], self.manager) |
|
139 |
|
|
140 |
def test_maps_links_no_rights(self): |
|
141 |
"""Cartes dans dialogue détails sans droits.""" |
|
142 |
idcorrevent = self._insert_dep() |
|
143 |
response = self.app.post('/plugin_json', { |
|
144 |
'idcorrevent': idcorrevent, |
|
145 |
'plugin_name': 'details', |
|
146 |
}, extra_environ={'REMOTE_USER': 'no_rights'}) |
|
147 |
# L'utilisateur n'a pas accès à VigiMap, donc il ne doit pas voir |
|
148 |
# les cartes, même s'il a accès à VigiBoard par ailleurs. |
|
149 |
self.assertEquals(response.json['maps'], {}) |
|
150 |
|
|
151 |
def test_maps_links_restricted(self): |
|
152 |
"""Cartes dans dialogue détails avec droits restreints.""" |
|
153 |
idcorrevent = self._insert_dep() |
|
154 |
response = self.app.post('/plugin_json', { |
|
155 |
'idcorrevent': idcorrevent, |
|
156 |
'plugin_name': 'details', |
|
157 |
}, extra_environ={'REMOTE_USER': 'restricted'}) |
|
158 |
# L'utilisateur ne doit voir que les cartes pour lesquelles |
|
159 |
# il a été autorisé. |
|
160 |
self.assertEquals(response.json['maps'], self.restricted) |
|
161 |
|
|
162 |
def test_maps_links_unrestricted(self): |
|
163 |
"""Cartes dans dialogue détails avec droits étendus.""" |
|
164 |
idcorrevent = self._insert_dep() |
|
165 |
response = self.app.post('/plugin_json', { |
|
166 |
'idcorrevent': idcorrevent, |
|
167 |
'plugin_name': 'details', |
|
168 |
}, extra_environ={'REMOTE_USER': 'unrestricted'}) |
|
169 |
# L'utilisateur ne doit voir que les cartes pour lesquelles |
|
170 |
# il a été autorisé (les mêmes que que "restricted" + "M2"). |
|
171 |
self.assertEquals(response.json['maps'], self.unrestricted) |
|
172 |
|
|
173 |
|
|
174 |
class TestDetailsPluginMapsHostDisabled(TestDetailsPluginMapsHostLimited): |
|
175 |
""" |
|
176 |
Teste la désactivation de l'affichage des cartes |
|
177 |
dans le module de détails. |
|
178 |
""" |
|
179 |
application_under_test = 'disabled_maps' |
|
180 |
# La réponse ne doit contenir aucune carte, |
|
181 |
# quel que soit l'utilisateur qui interroge |
|
182 |
# VigiBoard (la fonctionnalité est désactivée). |
|
183 |
manager = {} |
|
184 |
unrestricted = {} |
|
185 |
restricted = {} |
|
186 |
|
|
187 |
def shortDescription(self, *args, **kwargs): |
|
188 |
"""Description courte du test en cours d'exécution.""" |
|
189 |
res = TestController.shortDescription(*args, **kwargs) |
|
190 |
return "%s (disabled + host)" % (res, ) |
|
191 |
|
|
192 |
|
|
193 |
class TestDetailsPluginMapsHostUnlimited(TestDetailsPluginMapsHostLimited): |
|
194 |
""" |
|
195 |
Teste l'affichage des cartes dans le module de détails |
|
196 |
lorsqu'il n'y a aucun limite. |
|
197 |
""" |
|
198 |
application_under_test = 'unlimited_maps' |
|
199 |
# Le manager voit tout et en particulier les 3 cartes sur lesquelles |
|
200 |
# l'hôte apparaît. M1 ne doit apparaître qu'une seule fois |
|
201 |
# même si l'hôte est présent 2 fois sur la carte. |
|
202 |
manager = {'1': 'M1', '3': 'M3', '2': 'M2'} |
|
203 |
# L'utilisateur avec droits étendus voit |
|
204 |
# la même chose que le manager (3 cartes). |
|
205 |
unrestricted = manager.copy() |
|
206 |
# L'utilisateur avec droits restreints ne voit pas 'M2'. |
|
207 |
restricted = {'2': 'M2'} |
|
208 |
|
|
209 |
def shortDescription(self, *args, **kwargs): |
|
210 |
"""Description courte du test en cours d'exécution.""" |
|
211 |
res = TestController.shortDescription(*args, **kwargs) |
|
212 |
return "%s (unlimited + host)" % (res, ) |
|
213 |
|
|
214 |
class TestDetailsPluginMapsServiceLimited( |
|
215 |
TestDetailsPluginMapsHostLimited): |
|
216 |
""" |
|
217 |
Idem que la classe mère mais teste un événement corrélé |
|
218 |
portant sur un service de l'hôte plutôt que sur l'hôte lui-même. |
|
219 |
""" |
|
220 |
supitem_class = LowLevelService |
|
221 |
|
|
222 |
def shortDescription(self, *args, **kwargs): |
|
223 |
"""Description courte du test en cours d'exécution.""" |
|
224 |
# On court-circuite la hiérarchie de classes |
|
225 |
# pour appeler directement la méthode de nose/unittest. |
|
226 |
res = TestController.shortDescription(*args, **kwargs) |
|
227 |
return "%s (limited + service)" % (res, ) |
|
228 |
|
|
229 |
class TestDetailsPluginMapsServiceDisable( |
|
230 |
TestDetailsPluginMapsHostDisabled): |
|
231 |
""" |
|
232 |
Idem que la classe mère mais teste un événement corrélé |
|
233 |
portant sur un service de l'hôte plutôt que sur l'hôte lui-même. |
|
234 |
""" |
|
235 |
supitem_class = LowLevelService |
|
236 |
|
|
237 |
def shortDescription(self, *args, **kwargs): |
|
238 |
"""Description courte du test en cours d'exécution.""" |
|
239 |
# On court-circuite la hiérarchie de classes |
|
240 |
# pour appeler directement la méthode de nose/unittest. |
|
241 |
res = TestController.shortDescription(*args, **kwargs) |
|
242 |
return "%s (disabled + service)" % (res, ) |
|
243 |
|
|
244 |
class TestDetailsPluginMapsServiceUnlimited( |
|
245 |
TestDetailsPluginMapsHostUnlimited): |
|
246 |
""" |
|
247 |
Idem que la classe mère mais teste un événement corrélé |
|
248 |
portant sur un service de l'hôte plutôt que sur l'hôte lui-même. |
|
249 |
""" |
|
250 |
supitem_class = LowLevelService |
|
251 |
|
|
252 |
def shortDescription(self, *args, **kwargs): |
|
253 |
"""Description courte du test en cours d'exécution.""" |
|
254 |
# On court-circuite la hiérarchie de classes |
|
255 |
# pour appeler directement la méthode de nose/unittest. |
|
256 |
res = TestController.shortDescription(*args, **kwargs) |
|
257 |
return "%s (unlimited + service)" % (res, ) |
Also available in: Unified diff