Project

General

Profile

Revision 180b869a

ID180b869a74468693c2814f54938144cf28366519
Parent 2d135e67
Child dab61c72

Added by Vincent QUEMENER about 13 years ago

- Ajout d'une vue ('UserSupItem') représentant les supitems auxquels les utilisateurs ont accès ;
- Implémentation de l'utilisation de cette vue dans VigiBoard en vue de simplifier le code et d'en améliorer les performances en diminuant le nombre de lignes sur lesquelles portent les jointures (gain sensible lorsque le nombre d'évènements à afficher est élevé).

git-svn-id: https://vigilo-dev.si.c-s.fr/svn@6664 b22e2e97-25c9-44ff-b637-2e5ceca36478

View differences:

vigiboard/controllers/vigiboardrequest.py
21 21
"""Gestion de la requête, des plugins et de l'affichage du Vigiboard"""
22 22

  
23 23
from time import mktime
24
from logging import getLogger
25 24

  
26 25
from tg import config, tmpl_context, request, url
27 26
from pylons.i18n import ugettext as _
......
34 33

  
35 34
from vigilo.models.session import DBSession
36 35
from vigilo.models.tables import Event, CorrEvent, EventHistory, \
37
                        Host, LowLevelService, StateName, DataPermission
36
    Host, LowLevelService, StateName, DataPermission, UserSupItem
38 37
from vigilo.models.tables.grouphierarchy import GroupHierarchy
39 38
from vigilo.models.tables.secondary_tables import SUPITEM_GROUP_TABLE, \
40 39
        USER_GROUP_TABLE
41 40
from vigiboard.widgets.edit_event import EditEventForm
42 41
from vigiboard.controllers.plugins import VigiboardRequestPlugin
43 42

  
44
LOGGER = getLogger(__name__)
45

  
46 43
class VigiboardRequest():
47 44
    """
48 45
    Classe gérant la génération de la requête finale,
......
55 52
        'AAClosed': '_Ack',
56 53
    }
57 54

  
58
    def __init__(self, user, mask_closed_events=True):
55
    def __init__(self, user, mask_closed_events=True, supitemgroup=None):
59 56
        """
60 57
        Initialisation de l'objet qui effectue les requêtes de VigiBoard
61 58
        sur la base de données.
......
67 64

  
68 65
        is_manager = in_group('managers').is_met(request.environ)
69 66

  
70
        # Sélectionne tous les IDs des services auxquels
71
        # l'utilisateur a accès.
72
        lls_query = DBSession.query(
73
            LowLevelService.idservice.label("idsupitem"),
74
            LowLevelService.servicename.label("servicename"),
75
            Host.name.label("hostname"),
76
            SUPITEM_GROUP_TABLE.c.idgroup.label("idsupitemgroup"),
77
        ).join(
78
            (Host, Host.idhost == LowLevelService.idhost),
79
        ).outerjoin(
80
            (SUPITEM_GROUP_TABLE,
81
                or_(
82
                    SUPITEM_GROUP_TABLE.c.idsupitem == \
83
                        LowLevelService.idhost,
84
                    SUPITEM_GROUP_TABLE.c.idsupitem == \
85
                        LowLevelService.idservice,
67
        # Si l'utilisateur fait partie du groupe 'managers',
68
        # il a accès à tous les hôtes/services sans restriction.
69
        if is_manager:
70

  
71
            # Sélection de tous les services de la BDD.
72
            self.lls_query = DBSession.query(
73
                LowLevelService.idservice.label("idsupitem"),
74
                LowLevelService.servicename.label("servicename"),
75
                Host.name.label("hostname"),
76
            ).join(
77
                (Host, Host.idhost == LowLevelService.idhost),
78
            )
79
            
80
            # Ajout d'un filtre sur le groupe de supitems
81
            if supitemgroup:
82
                self.lls_query = self.lls_query.join(
83
                    (SUPITEM_GROUP_TABLE,
84
                        or_(
85
                            SUPITEM_GROUP_TABLE.c.idsupitem == \
86
                                LowLevelService.idhost,
87
                            SUPITEM_GROUP_TABLE.c.idsupitem == \
88
                                LowLevelService.idservice,
89
                        )
90
                    ),
91
                    (GroupHierarchy, GroupHierarchy.idchild == 
92
                        SUPITEM_GROUP_TABLE.c.idgroup)
93
                ).filter(
94
                    GroupHierarchy.idparent == supitemgroup
95
                )
96

  
97
            self.lls_query = self.lls_query.distinct()
98

  
99
            # Sélection de tous les hôtes de la BDD.
100
            self.host_query = DBSession.query(
101
                Host.idhost.label("idsupitem"),
102
                expr_null().label("servicename"),
103
                Host.name.label("hostname"),
104
            )
105
            
106
            # Ajout d'un filtre sur le groupe de supitems
107
            if supitemgroup:
108
                self.host_query = self.host_query.join(
109
                    (SUPITEM_GROUP_TABLE,
110
                        SUPITEM_GROUP_TABLE.c.idsupitem == \
111
                            Host.idhost,
112
                    ),
113
                    (GroupHierarchy, GroupHierarchy.idchild == 
114
                        SUPITEM_GROUP_TABLE.c.idgroup)
115
                ).filter(
116
                    GroupHierarchy.idparent == supitemgroup
117
                )
118

  
119
            self.host_query = self.host_query.distinct()
120

  
121
            # Union des deux sélections précédentes
122
            self.items = union_all(
123
                self.lls_query,
124
                self.host_query,
125
                correlate=False
126
            ).alias()
127

  
128
        # Sinon, on ne récupère que les hôtes/services auquel il a accès.
129
        else:
130
            self.items = DBSession.query(
131
                UserSupItem.idsupitem,
132
                UserSupItem.servicename,
133
                UserSupItem.hostname,
134
            ).filter(
135
                UserSupItem.username == user.user_name
136
            )
137

  
138
            # Ajout d'un filtre sur le groupe de supitems
139
            if supitemgroup:
140
                self.items = self.items.filter(
141
                    UserSupItem.idsupitemgroup == supitemgroup
86 142
                )
87
            ),
88
        )
89

  
90
        # Sélectionne tous les IDs des hôtes auxquels
91
        # l'utilisateur a accès.
92
        host_query = DBSession.query(
93
            Host.idhost.label("idsupitem"),
94
            expr_null().label("servicename"),
95
            Host.name.label("hostname"),
96
            SUPITEM_GROUP_TABLE.c.idgroup.label('idsupitemgroup'),
97
        ).join(
98
            (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
99
                Host.idhost),
100
        )
101

  
102
        # Les managers ont accès à tout, les autres sont soumis
103
        # aux vérifications classiques d'accès aux données.
104
        if not is_manager:
105

  
106
            lls_query = lls_query.join(
107
                (GroupHierarchy,
108
                    GroupHierarchy.idchild == SUPITEM_GROUP_TABLE.c.idgroup),
109
                (DataPermission,
110
                    DataPermission.idgroup == GroupHierarchy.idparent),
111
                (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \
112
                    DataPermission.idusergroup),
113
            ).filter(USER_GROUP_TABLE.c.username == user.user_name)
114

  
115
            host_query = host_query.join(
116
                (GroupHierarchy,
117
                    GroupHierarchy.idchild == SUPITEM_GROUP_TABLE.c.idgroup),
118
                (DataPermission,
119
                    DataPermission.idgroup == GroupHierarchy.idparent),
120
                (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \
121
                    DataPermission.idusergroup),
122
            ).filter(USER_GROUP_TABLE.c.username == user.user_name)
123

  
124
        # Objet Selectable renvoyant des informations sur un SupItem
125
        # concerné par une alerte, avec prise en compte des droits d'accès.
126
        # On est obligés d'utiliser sqlalchemy.sql.expression.union_all
127
        # pour indiquer à SQLAlchemy de NE PAS regrouper les tables
128
        # dans la requête principale, sans quoi les résultats sont
129
        # incorrects.
130
        # Dans PostgreSQL, UNION ALL est beaucoup plus rapide que UNION
131
        # du fait des performances limitées du DISTINCT.
132
        self.items = union_all(lls_query, host_query, correlate=False).alias()
143
            
144
            self.items = self.items.distinct().subquery()
133 145

  
134 146
        # Éléments à retourner (SELECT ...)
135 147
        self.table = []

Also available in: Unified diff