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/plugins/groups.py
31 31
from vigilo.models.tables.group import Group
32 32
from vigilo.models.tables.grouphierarchy import GroupHierarchy
33 33

  
34
from repoze.what.predicates import in_group
35
from tg import request
36

  
34 37
class GroupSelector(twf.InputField):
35 38
    params = ["choose_text", "text_value", "clear_text"]
36 39
    choose_text = l_('Choose')
......
76 79
        ]
77 80

  
78 81
    def handle_search_fields(self, query, search):
79
        if search.get('supitemgroup'):
80
            query.add_join((GroupHierarchy, GroupHierarchy.idchild ==
81
                query.items.c.idsupitemgroup))
82
            query.add_filter(GroupHierarchy.idparent ==
83
                search['supitemgroup'])
82
        pass
vigiboard/controllers/root.py
130 130
            - VIGILO_EXIG_VIGILO_BAC_0070,
131 131
            - VIGILO_EXIG_VIGILO_BAC_0100,
132 132
        """
133

  
133 134
        user = get_current_user()
134
        aggregates = VigiboardRequest(user)
135
        if 'supitemgroup' in search:
136
            aggregates = VigiboardRequest(
137
                user, supitemgroup=search['supitemgroup'])
138
        else:
139
            aggregates = VigiboardRequest(user)
135 140

  
136 141
        aggregates.add_table(
137 142
            CorrEvent,
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 = []
vigiboard/tests/functional/test_search_form_supitemgroup.py
110 110
        print "There are %d columns in the result set" % len(cols)
111 111
        assert_true(len(cols) > 1)
112 112

  
113
        # Mêmes tests avec un utilisateur membre du groupe 'managers'
114
        response = self.app.get('/?supitemgroup=%d' % idgroup,
115
            extra_environ={'REMOTE_USER': 'manager'})
116
        rows = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr')
117
        print "There are %d rows in the result set" % len(rows)
118
        assert_equal(len(rows), 1)
119
        cols = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr/td')
120
        print "There are %d columns in the result set" % len(cols)
121
        assert_true(len(cols) > 1)
122

  
113 123
    def test_search_inexistent_supitemgroup(self):
114 124
        """Teste la recherche par supitemgroup sur un groupe inexistant."""
115 125
        # On envoie une requête avec recherche sur un groupe d'hôtes
......
129 139
        print "There are %d columns in the result set" % len(cols)
130 140
        assert_equal(len(cols), 1)
131 141

  
142
        # Mêmes tests avec un utilisateur membre du groupe 'managers'
143
        response = self.app.get('/?supitemgroup=%d' % -42,
144
            extra_environ={'REMOTE_USER': 'manager'})
145
        rows = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr')
146
        print "There are %d rows in the result set" % len(rows)
147
        assert_equal(len(rows), 1)
148
        cols = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr/td')
149
        print "There are %d columns in the result set" % len(cols)
150
        assert_equal(len(cols), 1)
151

  
132 152
    def test_search_supitemgroup_when_disallowed(self):
133 153
        """Teste la recherche par supitemgroup SANS les droits d'accès."""
134 154
        # On crée un groupe d'hôte appelé 'foo',

Also available in: Unified diff