Revision 86662bc9
Correction recherche par supitemgroup (#595).
Corrige le cas où on a 1 étage ou plus séparément le père sur lequel on a les droits
du (petit...)-fils auquel appartient l'élément supervisé sur lequel l'événement est
survenu.
L'ajout des critères de recherche à la requête se fait désormais en 2 phases :
- la 1ère phase permet d'ajouter les critères sur les sous-requêtes (phase INNER)
- la 2nde phase permet d'ajouter les critères sur l'union (phase ITEMS)
git-svn-id: https://vigilo-dev.si.c-s.fr/svn@6691 b22e2e97-25c9-44ff-b637-2e5ceca36478
vigiboard/controllers/plugins/__init__.py | ||
---|---|---|
22 | 22 |
Module complémentaire générique. |
23 | 23 |
""" |
24 | 24 |
|
25 |
from pylons.i18n import ugettext as _ |
|
25 |
# État lorsque les plugins sont appelés avec les sous-requêtes. |
|
26 |
INNER = 0 |
|
27 |
# État lorsque les plugins sont appelés lorsque "items" est défini. |
|
28 |
ITEMS = 1 |
|
29 |
|
|
26 | 30 |
|
27 | 31 |
class VigiboardRequestPlugin(object): |
28 | 32 |
""" |
... | ... | |
90 | 94 |
def get_search_fields(self): |
91 | 95 |
return [] |
92 | 96 |
|
93 |
def handle_search_fields(self, query, search, subqueries):
|
|
97 |
def handle_search_fields(self, query, search, state, subqueries=None):
|
|
94 | 98 |
pass |
vigiboard/controllers/plugins/date.py | ||
---|---|---|
29 | 29 |
|
30 | 30 |
from vigilo.models import tables |
31 | 31 |
|
32 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
32 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
|
|
33 | 33 |
from vigiboard.lib.dateformat import DateFormatConverter |
34 | 34 |
|
35 | 35 |
def get_calendar_lang(): |
... | ... | |
77 | 77 |
), |
78 | 78 |
] |
79 | 79 |
|
80 |
def handle_search_fields(self, query, search, subqueries): |
|
80 |
def handle_search_fields(self, query, search, state, subqueries): |
|
81 |
if state != ITEMS: |
|
82 |
return |
|
83 |
|
|
81 | 84 |
if search.get('from_date'): |
82 | 85 |
query.add_filter(tables.CorrEvent.timestamp_active >= |
83 | 86 |
search['from_date']) |
vigiboard/controllers/plugins/groups.py | ||
---|---|---|
26 | 26 |
import tw.forms as twf |
27 | 27 |
from pylons.i18n import lazy_ugettext as l_ |
28 | 28 |
|
29 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
29 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, INNER
|
|
30 | 30 |
from vigilo.models.session import DBSession |
31 | 31 |
from vigilo.models import tables |
32 | 32 |
from vigilo.models.tables.group import Group |
... | ... | |
36 | 36 |
|
37 | 37 |
from repoze.what.predicates import in_group |
38 | 38 |
from tg import request |
39 |
from sqlalchemy import or_ |
|
39 | 40 |
|
40 | 41 |
class GroupSelector(twf.InputField): |
41 | 42 |
params = ["choose_text", "text_value", "clear_text"] |
... | ... | |
81 | 82 |
) |
82 | 83 |
] |
83 | 84 |
|
84 |
def handle_search_fields(self, query, search, subqueries): |
|
85 |
if search.get('supitemgroup') is None: |
|
85 |
def handle_search_fields(self, query, search, state, subqueries):
|
|
86 |
if search.get('supitemgroup') is None or state != INNER:
|
|
86 | 87 |
return |
87 | 88 |
|
88 | 89 |
# Il s'agit d'un manager. On applique le filtre |
vigiboard/controllers/plugins/hostname.py | ||
---|---|---|
25 | 25 |
from pylons.i18n import lazy_ugettext as l_ |
26 | 26 |
|
27 | 27 |
from vigilo.models.functions import sql_escape_like |
28 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
28 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
|
|
29 | 29 |
|
30 | 30 |
class PluginHostname(VigiboardRequestPlugin): |
31 | 31 |
""" |
... | ... | |
40 | 40 |
) |
41 | 41 |
] |
42 | 42 |
|
43 |
def handle_search_fields(self, query, search, subqueries): |
|
43 |
def handle_search_fields(self, query, search, state, subqueries): |
|
44 |
if state != ITEMS: |
|
45 |
return |
|
46 |
|
|
44 | 47 |
if search.get('host'): |
45 | 48 |
host = sql_escape_like(search['host']) |
46 | 49 |
query.add_filter(query.items.c.hostname.ilike(host)) |
vigiboard/controllers/plugins/output.py | ||
---|---|---|
27 | 27 |
|
28 | 28 |
from vigilo.models.tables import Event |
29 | 29 |
from vigilo.models.functions import sql_escape_like |
30 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
30 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
|
|
31 | 31 |
|
32 | 32 |
class PluginOutput(VigiboardRequestPlugin): |
33 | 33 |
"""Ajoute une colonne avec le message de Nagios.""" |
... | ... | |
40 | 40 |
) |
41 | 41 |
] |
42 | 42 |
|
43 |
def handle_search_fields(self, query, search, subqueries): |
|
43 |
def handle_search_fields(self, query, search, state, subqueries): |
|
44 |
if state != ITEMS: |
|
45 |
return |
|
46 |
|
|
44 | 47 |
if search.get('output'): |
45 | 48 |
output = sql_escape_like(search['output']) |
46 | 49 |
query.add_filter(Event.message.ilike(output)) |
vigiboard/controllers/plugins/priority.py | ||
---|---|---|
27 | 27 |
from formencode import schema, validators |
28 | 28 |
|
29 | 29 |
from vigilo.models.tables import CorrEvent |
30 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
30 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
|
|
31 | 31 |
|
32 | 32 |
from tw.forms.fields import ContainerMixin, FormField |
33 | 33 |
from tw.core.base import WidgetsList |
... | ... | |
109 | 109 |
) |
110 | 110 |
] |
111 | 111 |
|
112 |
def handle_search_fields(self, query, search, subqueries): |
|
113 |
if (not search.get('priority')): |
|
112 |
def handle_search_fields(self, query, search, state, subqueries):
|
|
113 |
if (not search.get('priority')) or state != ITEMS:
|
|
114 | 114 |
return |
115 | 115 |
|
116 | 116 |
op = search['priority']['op'] |
vigiboard/controllers/plugins/servicename.py | ||
---|---|---|
26 | 26 |
from pylons.i18n import lazy_ugettext as l_ |
27 | 27 |
|
28 | 28 |
from vigilo.models.functions import sql_escape_like |
29 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
29 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
|
|
30 | 30 |
|
31 | 31 |
class PluginServicename(VigiboardRequestPlugin): |
32 | 32 |
""" |
... | ... | |
43 | 43 |
) |
44 | 44 |
] |
45 | 45 |
|
46 |
def handle_search_fields(self, query, search, subqueries): |
|
46 |
def handle_search_fields(self, query, search, state, subqueries): |
|
47 |
if state != ITEMS: |
|
48 |
return |
|
49 |
|
|
47 | 50 |
if search.get('service'): |
48 | 51 |
service = sql_escape_like(search['service']) |
49 | 52 |
query.add_filter(query.items.c.servicename.ilike(service)) |
vigiboard/controllers/plugins/status.py | ||
---|---|---|
31 | 31 |
|
32 | 32 |
from vigilo.models.tables import CorrEvent |
33 | 33 |
from vigilo.models.functions import sql_escape_like |
34 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
34 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
|
|
35 | 35 |
|
36 | 36 |
class PluginStatus(VigiboardRequestPlugin): |
37 | 37 |
""" |
... | ... | |
55 | 55 |
) |
56 | 56 |
] |
57 | 57 |
|
58 |
def handle_search_fields(self, query, search, subqueries): |
|
58 |
def handle_search_fields(self, query, search, state, subqueries): |
|
59 |
if state != ITEMS: |
|
60 |
return |
|
61 |
|
|
59 | 62 |
if search.get('trouble_ticket'): |
60 | 63 |
tt = sql_escape_like(search['trouble_ticket']) |
61 | 64 |
query.add_filter(CorrEvent.trouble_ticket.ilike(tt)) |
vigiboard/controllers/vigiboardrequest.py | ||
---|---|---|
37 | 37 |
from vigilo.models.tables.grouphierarchy import GroupHierarchy |
38 | 38 |
from vigilo.models.tables.secondary_tables import SUPITEM_GROUP_TABLE |
39 | 39 |
from vigiboard.widgets.edit_event import EditEventForm |
40 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin |
|
40 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, INNER, ITEMS
|
|
41 | 41 |
|
42 | 42 |
class VigiboardRequest(): |
43 | 43 |
""" |
... | ... | |
63 | 63 |
self.subqueries = [] |
64 | 64 |
self.generaterq = False |
65 | 65 |
|
66 |
# Éléments à retourner (SELECT ...) |
|
67 |
self.table = [] |
|
68 |
|
|
69 |
# Tables sur lesquelles porte la récupération (JOIN) |
|
70 |
self.join = [] |
|
71 |
|
|
72 |
# Options à ajouter la requête |
|
73 |
self.option = [] |
|
74 |
|
|
75 |
# Tables sur lesquelles porte la récupération (OUTER JOIN) |
|
76 |
self.outerjoin = [] |
|
77 |
|
|
78 |
# Critères de filtrage (WHERE) |
|
79 |
self.filter = [] |
|
80 |
|
|
81 |
# Regroupements (GROUP BY) |
|
82 |
# PostgreSQL est pointilleux sur les colonnes qui apparaissent |
|
83 |
# dans la clause GROUP BY. Si une colonne apparaît dans ORDER BY, |
|
84 |
# elle doit systématiquement apparaître AUSSI dans GROUP BY. |
|
85 |
self.groupby = [ |
|
86 |
StateName.order, |
|
87 |
Event.timestamp, |
|
88 |
CorrEvent.status, |
|
89 |
CorrEvent.priority, |
|
90 |
StateName.statename, |
|
91 |
] |
|
92 |
|
|
93 |
# Permet de définir le sens de tri pour la priorité. |
|
94 |
if config['vigiboard_priority_order'] == 'asc': |
|
95 |
priority_order = asc(CorrEvent.priority) |
|
96 |
else: |
|
97 |
priority_order = desc(CorrEvent.priority) |
|
98 |
|
|
99 |
# Tris (ORDER BY) |
|
100 |
# Permet de répondre aux exigences suivantes : |
|
101 |
# - VIGILO_EXIG_VIGILO_BAC_0050 |
|
102 |
# - VIGILO_EXIG_VIGILO_BAC_0060 |
|
103 |
self.orderby = [ |
|
104 |
desc(CorrEvent.status), # État acquittement |
|
105 |
asc(StateName.statename.in_([u'OK', u'UP'])), # Vert / Pas vert |
|
106 |
priority_order, # Priorité ITIL |
|
107 |
] |
|
108 |
|
|
109 |
if asbool(config.get('state_first', True)): |
|
110 |
self.orderby.extend([ |
|
111 |
desc(StateName.order), # Etat courant |
|
112 |
desc(Event.timestamp), # Timestamp |
|
113 |
]) |
|
114 |
else: |
|
115 |
self.orderby.extend([ |
|
116 |
desc(Event.timestamp), # Timestamp |
|
117 |
desc(StateName.order), # Etat courant |
|
118 |
]) |
|
119 |
|
|
120 |
self.req = DBSession |
|
121 |
self.plugin = [] |
|
122 |
self.events = [] |
|
123 |
|
|
124 |
|
|
66 | 125 |
is_manager = in_group('managers').is_met(request.environ) |
67 | 126 |
|
68 | 127 |
# Si l'utilisateur fait partie du groupe 'managers', |
... | ... | |
90 | 149 |
# par référence dans les fonctions. |
91 | 150 |
subqueries = [lls_query, host_query] |
92 | 151 |
for plugin, instance in config.get('columns_plugins', []): |
93 |
instance.handle_search_fields(self, search, subqueries) |
|
152 |
instance.handle_search_fields( |
|
153 |
self, search, INNER, subqueries) |
|
94 | 154 |
lls_query = subqueries[0] |
95 | 155 |
host_query = subqueries[1] |
96 | 156 |
|
... | ... | |
117 | 177 |
# par référence dans les fonctions. |
118 | 178 |
subqueries = [items] |
119 | 179 |
for plugin, instance in config.get('columns_plugins', []): |
120 |
instance.handle_search_fields(self, search, subqueries) |
|
180 |
instance.handle_search_fields( |
|
181 |
self, search, INNER, subqueries) |
|
121 | 182 |
items = subqueries[0] |
122 | 183 |
|
184 |
# Permet d'avoir le même format que pour l'autre requête. |
|
123 | 185 |
self.items = items.subquery() |
124 | 186 |
|
125 |
# Éléments à retourner (SELECT ...) |
|
126 |
self.table = [] |
|
127 |
|
|
128 |
# Tables sur lesquelles porte la récupération (JOIN) |
|
129 |
self.join = [] |
|
187 |
if search is not None: |
|
188 |
# 2nde passe pour les filtres : self.items est désormais défini. |
|
189 |
for plugin, instance in config.get('columns_plugins', []): |
|
190 |
instance.handle_search_fields(self, search, ITEMS, subqueries) |
|
130 | 191 |
|
131 |
# Options à ajouter la requête |
|
132 |
self.option = [] |
|
133 |
|
|
134 |
# Tables sur lesquelles porte la récupération (OUTER JOIN) |
|
135 |
self.outerjoin = [] |
|
136 |
|
|
137 |
# Critères de filtrage (WHERE) |
|
138 |
self.filter = [] |
|
139 | 192 |
if mask_closed_events: |
140 | 193 |
self.filter.append( |
141 | 194 |
# On masque les événements avec l'état OK |
... | ... | |
146 | 199 |
)) |
147 | 200 |
) |
148 | 201 |
|
149 |
# Permet de définir le sens de tri pour la priorité. |
|
150 |
if config['vigiboard_priority_order'] == 'asc': |
|
151 |
priority_order = asc(CorrEvent.priority) |
|
152 |
else: |
|
153 |
priority_order = desc(CorrEvent.priority) |
|
154 |
|
|
155 |
# Tris (ORDER BY) |
|
156 |
# Permet de répondre aux exigences suivantes : |
|
157 |
# - VIGILO_EXIG_VIGILO_BAC_0050 |
|
158 |
# - VIGILO_EXIG_VIGILO_BAC_0060 |
|
159 |
self.orderby = [ |
|
160 |
desc(CorrEvent.status), # État acquittement |
|
161 |
asc(StateName.statename.in_([u'OK', u'UP'])), # Vert / Pas vert |
|
162 |
priority_order, # Priorité ITIL |
|
163 |
] |
|
164 |
|
|
165 |
if asbool(config.get('state_first', True)): |
|
166 |
self.orderby.extend([ |
|
167 |
desc(StateName.order), # Etat courant |
|
168 |
desc(Event.timestamp), # Timestamp |
|
169 |
]) |
|
170 |
else: |
|
171 |
self.orderby.extend([ |
|
172 |
desc(Event.timestamp), # Timestamp |
|
173 |
desc(StateName.order), # Etat courant |
|
174 |
]) |
|
175 |
|
|
176 |
|
|
177 |
# Regroupements (GROUP BY) |
|
178 |
# PostgreSQL est pointilleux sur les colonnes qui apparaissent |
|
179 |
# dans la clause GROUP BY. Si une colonne apparaît dans ORDER BY, |
|
180 |
# elle doit systématiquement apparaître AUSSI dans GROUP BY. |
|
181 |
self.groupby = [ |
|
182 |
StateName.order, |
|
183 |
Event.timestamp, |
|
184 |
CorrEvent.status, |
|
185 |
CorrEvent.priority, |
|
186 |
StateName.statename, |
|
187 |
] |
|
188 |
|
|
189 |
self.plugin = [] |
|
190 |
self.events = [] |
|
191 |
self.req = DBSession |
|
192 | 202 |
|
193 | 203 |
def add_plugin(self, *argv): |
194 | 204 |
""" |
Also available in: Unified diff