views.py 24.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017  Gabriel Détraz
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
chirac's avatar
chirac committed
22 23
"""
Page des vues de l'application topologie
24

chirac's avatar
chirac committed
25 26 27 28 29 30 31 32 33 34 35
Permet de créer, modifier et supprimer :
- un port (add_port, edit_port, del_port)
- un switch : les vues d'ajout et d'édition font appel aux forms de creation
de switch, mais aussi aux forms de machines.forms (domain, interface et
machine). Le views les envoie et les save en même temps. TODO : rationaliser
et faire que la creation de machines (interfaces, domain etc) soit gérée
coté models et forms de topologie
- une chambre (new_room, edit_room, del_room)
- une stack
- l'historique de tous les objets cités
"""
36 37
from __future__ import unicode_literals

38
from django.urls import reverse
Dalahro's avatar
Dalahro committed
39 40
from django.shortcuts import render, redirect
from django.contrib import messages
41
from django.contrib.auth.decorators import login_required, permission_required
Dalahro's avatar
Dalahro committed
42
from django.db import IntegrityError
43
from django.db import transaction
44
from django.db.models import ProtectedError, Prefetch
45
from django.core.exceptions import ValidationError
chirac's avatar
chirac committed
46
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
Dalahro's avatar
Dalahro committed
47

48 49 50 51 52 53
from topologie.models import (
    Switch,
    Port,
    Room,
    Stack,
    ModelSwitch,
54
    ConstructorSwitch,
55
    AccessPoint
56
)
chirac's avatar
chirac committed
57
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
58 59 60 61
from topologie.forms import (
    AddPortForm,
    EditRoomForm,
    StackForm,
62
    EditModelSwitchForm,
63
    EditConstructorSwitchForm,
64
    CreatePortsForm,
65 66
    AddAccessPointForm,
    EditAccessPointForm
67
)
Dalahro's avatar
Dalahro committed
68
from users.views import form
69 70
from re2o.utils import SortTable
from re2o.acl import (
71 72 73
    can_create,
    can_edit,
    can_delete,
74 75
    can_view,
    can_view_all,
76
)
77 78 79 80 81 82 83
from machines.forms import (
    DomainForm,
    NewMachineForm,
    EditMachineForm,
    EditInterfaceForm,
    AddInterfaceForm
)
84
from machines.views import generate_ipv4_mbf_param
85
from machines.models import Interface
86
from preferences.models import AssoOption, GeneralOption
87

chirac's avatar
chirac committed
88

chirac's avatar
chirac committed
89
@login_required
90
@can_view_all(Switch)
Dalahro's avatar
Dalahro committed
91
def index(request):
92
    """ Vue d'affichage de tous les swicthes"""
93
    switch_list = Switch.objects\
94 95 96 97
        .prefetch_related(Prefetch(
            'interface_set',
        queryset=Interface.objects.select_related('ipv4__ip_type__extension').select_related('domain__extension')
        ))\
chirac's avatar
chirac committed
98
        .select_related('stack')
99 100 101 102 103 104
    switch_list = SortTable.sort(
        switch_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX
    )
105
    pagination_number = GeneralOption.get_cached_value('pagination_number')
Gabriel Detraz's avatar
Gabriel Detraz committed
106 107 108 109 110 111 112 113 114 115
    paginator = Paginator(switch_list, pagination_number)
    page = request.GET.get('page')
    try:
        switch_list = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        switch_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        switch_list = paginator.page(paginator.num_pages)
chirac's avatar
chirac committed
116 117 118 119
    return render(request, 'topologie/index.html', {
        'switch_list': switch_list
        })

Dalahro's avatar
Dalahro committed
120

chirac's avatar
chirac committed
121
@login_required
122 123
@can_view_all(Port)
@can_view(Switch)
124
def index_port(request, switch, switchid):
125
    """ Affichage de l'ensemble des ports reliés à un switch particulier"""
chirac's avatar
chirac committed
126 127 128
    port_list = Port.objects.filter(switch=switch)\
        .select_related('room')\
        .select_related('machine_interface__domain__extension')\
129
        .select_related('machine_interface__machine__user')\
130
        .select_related('related__switch')\
131 132 133 134
        .prefetch_related(Prefetch(
            'related__switch__interface_set',
            queryset=Interface.objects.select_related('domain__extension')
        ))\
135 136 137 138 139 140 141
        .select_related('switch')
    port_list = SortTable.sort(
        port_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_PORT
    )
chirac's avatar
chirac committed
142 143
    return render(request, 'topologie/index_p.html', {
        'port_list': port_list,
144
        'id_switch': switchid,
chirac's avatar
chirac committed
145 146 147
        'nom_switch': switch
        })

Dalahro's avatar
Dalahro committed
148

chirac's avatar
chirac committed
149
@login_required
150
@can_view_all(Room)
chirac's avatar
chirac committed
151
def index_room(request):
152
    """ Affichage de l'ensemble des chambres"""
153
    room_list = Room.objects
154 155 156 157 158 159
    room_list = SortTable.sort(
        room_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_ROOM
    )
160
    pagination_number = GeneralOption.get_cached_value('pagination_number')
Gabriel Detraz's avatar
Gabriel Detraz committed
161 162 163 164 165 166 167 168 169 170
    paginator = Paginator(room_list, pagination_number)
    page = request.GET.get('page')
    try:
        room_list = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        room_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        room_list = paginator.page(paginator.num_pages)
chirac's avatar
chirac committed
171 172 173 174
    return render(request, 'topologie/index_room.html', {
        'room_list': room_list
        })

chirac's avatar
chirac committed
175

176
@login_required
177 178
@can_view_all(AccessPoint)
def index_ap(request):
179
    """ Affichage de l'ensemble des bornes"""
180 181 182 183 184
    ap_list = AccessPoint.objects\
        .prefetch_related(Prefetch(
            'interface_set',
            queryset=Interface.objects.select_related('ipv4__ip_type__extension').select_related('domain__extension')
        ))
185 186
    ap_list = SortTable.sort(
        ap_list,
187 188 189 190 191
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_BORNE
    )
    pagination_number = GeneralOption.get_cached_value('pagination_number')
192
    paginator = Paginator(ap_list, pagination_number)
193 194
    page = request.GET.get('page')
    try:
195
        ap_list = paginator.page(page)
196 197
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
198
        ap_list = paginator.page(1)
199 200
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
201 202 203
        ap_list = paginator.page(paginator.num_pages)
    return render(request, 'topologie/index_ap.html', {
        'ap_list': ap_list
204 205 206
        })


207
@login_required
208
@can_view_all(Stack)
209
def index_stack(request):
chirac's avatar
chirac committed
210
    """Affichage de la liste des stacks (affiche l'ensemble des switches)"""
211
    stack_list = Stack.objects\
212
        .prefetch_related('switch_set__domain__extension')
213 214 215 216 217 218
    stack_list = SortTable.sort(
        stack_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_STACK
    )
chirac's avatar
chirac committed
219 220 221
    return render(request, 'topologie/index_stack.html', {
        'stack_list': stack_list
        })
222 223


224
@login_required
225 226
@can_view_all(ModelSwitch)
@can_view_all(ConstructorSwitch)
227 228
def index_model_switch(request):
    """ Affichage de l'ensemble des modèles de switches"""
229
    model_switch_list = ModelSwitch.objects.select_related('constructor')
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
    constructor_switch_list = ConstructorSwitch.objects
    model_switch_list = SortTable.sort(
        model_switch_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_MODEL_SWITCH
    )
    constructor_switch_list = SortTable.sort(
        constructor_switch_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_CONSTRUCTOR_SWITCH
    )
    return render(request, 'topologie/index_model_switch.html', {
        'model_switch_list': model_switch_list,
        'constructor_switch_list': constructor_switch_list,
        })


chirac's avatar
chirac committed
249
@login_required
250
@can_create(Port)
251
def new_port(request, switchid):
252
    """ Nouveau port"""
Dalahro's avatar
Dalahro committed
253
    try:
254
        switch = Switch.objects.get(pk=switchid)
Dalahro's avatar
Dalahro committed
255 256
    except Switch.DoesNotExist:
        messages.error(request, u"Switch inexistant")
257
        return redirect(reverse('topologie:index'))
Dalahro's avatar
Dalahro committed
258 259 260 261 262
    port = AddPortForm(request.POST or None)
    if port.is_valid():
        port = port.save(commit=False)
        port.switch = switch
        try:
263
            port.save()
Dalahro's avatar
Dalahro committed
264 265
            messages.success(request, "Port ajouté")
        except IntegrityError:
chirac's avatar
chirac committed
266
            messages.error(request, "Ce port existe déjà")
267
        return redirect(reverse(
268
            'topologie:index-port',
269
            kwargs={'switchid':switchid}
270
            ))
271
    return form({'id_switch': switchid,'topoform': port, 'action_name' : 'Ajouter'}, 'topologie/topo.html', request)
chirac's avatar
chirac committed
272

Dalahro's avatar
Dalahro committed
273

chirac's avatar
chirac committed
274
@login_required
275
@can_edit(Port)
276
def edit_port(request, port_object, portid):
chirac's avatar
chirac committed
277 278
    """ Edition d'un port. Permet de changer le switch parent et
    l'affectation du port"""
279

280
    port = EditPortForm(request.POST or None, instance=port_object)
Dalahro's avatar
Dalahro committed
281
    if port.is_valid():
282
        port.save()
Dalahro's avatar
Dalahro committed
283
        messages.success(request, "Le port a bien été modifié")
284 285
        return redirect(reverse(
            'topologie:index-port',
286
            kwargs={'switchid': str(port_object.switch.id)}
287
            ))
288
    return form({'id_switch': str(port_object.switch.id), 'topoform': port, 'action_name' : 'Editer'}, 'topologie/topo.html', request)
chirac's avatar
chirac committed
289

chirac's avatar
chirac committed
290

291
@login_required
292
@can_delete(Port)
293
def del_port(request, port, portid):
294
    """ Supprime le port"""
Gabriel Detraz's avatar
Gabriel Detraz committed
295 296
    if request.method == "POST":
        try:
297 298
            port.delete()
            messages.success(request, "Le port a été détruit")
Gabriel Detraz's avatar
Gabriel Detraz committed
299
        except ProtectedError:
chirac's avatar
chirac committed
300 301
            messages.error(request, "Le port %s est affecté à un autre objet,\
                impossible de le supprimer" % port)
302 303
        return redirect(reverse(
            'topologie:index-port',
304
            kwargs={'switchid':str(port.switch.id)}
305
            ))
chirac's avatar
chirac committed
306 307
    return form({'objet': port}, 'topologie/delete.html', request)

Gabriel Detraz's avatar
Gabriel Detraz committed
308 309

@login_required
310
@can_create(Stack)
311
def new_stack(request):
312
    """Ajoute un nouveau stack : stackid_min, max, et nombre de switches"""
313
    stack = StackForm(request.POST or None)
chirac's avatar
chirac committed
314
    if stack.is_valid():
315
        stack.save()
chirac's avatar
chirac committed
316
        messages.success(request, "Stack crée")
317
    return form({'topoform': stack, 'action_name' : 'Créer'}, 'topologie/topo.html', request)
318 319 320


@login_required
321
@can_edit(Stack)
322
def edit_stack(request, stack, stackid):
chirac's avatar
chirac committed
323
    """Edition d'un stack (nombre de switches, nom...)"""
324 325
    stack = StackForm(request.POST or None, instance=stack)
    if stack.is_valid():
326 327
        stack.save()
        return redirect(reverse('topologie:index-stack'))
328
    return form({'topoform': stack, 'action_name' : 'Editer'}, 'topologie/topo.html', request)
chirac's avatar
chirac committed
329

330

331
@login_required
332
@can_delete(Stack)
333
def del_stack(request, stack, stackid):
chirac's avatar
chirac committed
334
    """Supprime un stack"""
335 336
    if request.method == "POST":
        try:
337 338
            stack.delete()
            messages.success(request, "La stack a eté détruite")
339
        except ProtectedError:
chirac's avatar
chirac committed
340 341
            messages.error(request, "La stack %s est affectée à un autre\
                objet, impossible de la supprimer" % stack)
342
        return redirect(reverse('topologie:index-stack'))
chirac's avatar
chirac committed
343 344
    return form({'objet': stack}, 'topologie/delete.html', request)

345

346
@login_required
347
@can_edit(Stack)
348
def edit_switchs_stack(request, stack, stackid):
chirac's avatar
chirac committed
349
    """Permet d'éditer la liste des switches dans une stack et l'ajouter"""
350

351 352 353 354 355 356 357 358
    if request.method == "POST":
        pass
    else:
        context = {'stack': stack}
        context['switchs_stack'] = stack.switchs_set.all()
        context['switchs_autres'] = Switch.object.filter(stack=None)


chirac's avatar
chirac committed
359
@login_required
360
@can_create(Switch)
Dalahro's avatar
Dalahro committed
361
def new_switch(request):
chirac's avatar
chirac committed
362 363 364
    """ Creation d'un switch. Cree en meme temps l'interface et la machine
    associée. Vue complexe. Appelle successivement les 4 models forms
    adaptés : machine, interface, domain et switch"""
365
    switch = NewSwitchForm(
366 367 368
        request.POST or None,
        user=request.user
    )
369
    interface = AddInterfaceForm(
chirac's avatar
chirac committed
370
        request.POST or None,
371
        user=request.user
372
    )
373
    domain = DomainForm(
chirac's avatar
chirac committed
374 375
        request.POST or None,
        )
376
    if switch.is_valid() and interface.is_valid():
377
        user = AssoOption.get_cached_value('utilisateur_asso')
378
        if not user:
chirac's avatar
chirac committed
379 380
            messages.error(request, "L'user association n'existe pas encore,\
            veuillez le créer ou le linker dans preferences")
381
            return redirect(reverse('topologie:index'))
382 383 384 385
        new_switch = switch.save(commit=False)
        new_switch.user = user
        new_interface_instance = interface.save(commit=False)
        domain.instance.interface_parent = new_interface_instance
386 387
        if domain.is_valid():
            new_domain_instance = domain.save(commit=False)
388
            new_switch.save()
389
            new_interface_instance.machine = new_switch
390
            new_interface_instance.save()
391
            new_domain_instance.interface_parent = new_interface_instance
392
            new_domain_instance.save()
393 394
            messages.success(request, "Le switch a été créé")
            return redirect(reverse('topologie:index'))
395
    i_mbf_param = generate_ipv4_mbf_param(interface, False)
chirac's avatar
chirac committed
396
    return form({
397 398
        'topoform': interface,
        'machineform': switch,
chirac's avatar
chirac committed
399
        'domainform': domain,
400 401 402
        'i_mbf_param': i_mbf_param,
        'device' : 'switch',
        }, 'topologie/topo_more.html', request)
chirac's avatar
chirac committed
403

Dalahro's avatar
Dalahro committed
404

405
@login_required
406
@can_create(Port)
407
def create_ports(request, switchid):
408 409
    """ Création d'une liste de ports pour un switch."""
    try:
410
        switch = Switch.objects.get(pk=switchid)
411 412
    except Switch.DoesNotExist:
        messages.error(request, u"Switch inexistant")
413
        return redirect(reverse('topologie:index'))
414

415
    s_begin = s_end = 0
416 417
    nb_ports = switch.ports.count()
    if nb_ports > 0:
Levy--Falk Hugo's avatar
Levy--Falk Hugo committed
418 419 420
        ports = switch.ports.order_by('port').values('port')
        s_begin = ports.first().get('port')
        s_end = ports.last().get('port')
421

422 423
    port_form = CreatePortsForm(
        request.POST or None,
424
        initial={'begin': s_begin, 'end': s_end}
425
    )
426

427 428 429
    if port_form.is_valid():
        begin = port_form.cleaned_data['begin']
        end = port_form.cleaned_data['end']
430 431 432 433 434
        try:
            switch.create_ports(begin, end)
            messages.success(request, "Ports créés.")
        except ValidationError as e:
            messages.error(request, ''.join(e))
435 436
        return redirect(reverse(
            'topologie:index-port',
437
            kwargs={'switchid':switchid}
438
            ))
439
    return form({'id_switch': switchid, 'topoform': port_form}, 'topologie/switch.html', request)
440

Dalahro's avatar
Dalahro committed
441

chirac's avatar
chirac committed
442
@login_required
443
@can_edit(Switch)
444
def edit_switch(request, switch, switchid):
chirac's avatar
chirac committed
445 446
    """ Edition d'un switch. Permet de chambre nombre de ports,
    place dans le stack, interface et machine associée"""
447

448
    switch_form = EditSwitchForm(
chirac's avatar
chirac committed
449
        request.POST or None,
450
        instance=switch,
451
        user=request.user
chirac's avatar
chirac committed
452
        )
453
    interface_form = EditInterfaceForm(
chirac's avatar
chirac committed
454
        request.POST or None,
455
        instance=switch.interface_set.first(),
456
        user=request.user
chirac's avatar
chirac committed
457
        )
458
    domain_form = DomainForm(
chirac's avatar
chirac committed
459
        request.POST or None,
460
        instance=switch.interface_set.first().domain
chirac's avatar
chirac committed
461
        )
462 463 464
    if switch_form.is_valid() and interface_form.is_valid():
        new_switch = switch_form.save(commit=False)
        new_interface_instance = interface_form.save(commit=False)
chirac's avatar
chirac committed
465
        new_domain = domain_form.save(commit=False)
466 467 468
        new_switch.save()
        new_interface_instance.save()
        new_domain.save()
469
        messages.success(request, "Le switch a bien été modifié")
Levy--Falk Hugo's avatar
Levy--Falk Hugo committed
470
        return redirect(reverse('topologie:index'))
471
    i_mbf_param = generate_ipv4_mbf_param(interface_form, False )
chirac's avatar
chirac committed
472
    return form({
473
        'id_switch': switchid,
474 475
        'topoform': interface_form,
        'machineform': switch_form,
chirac's avatar
chirac committed
476
        'domainform': domain_form,
477 478 479
        'i_mbf_param': i_mbf_param,
        'device' : 'switch',
        }, 'topologie/topo_more.html', request)
chirac's avatar
chirac committed
480

chirac's avatar
chirac committed
481

482
@login_required
483 484 485
@can_create(AccessPoint)
def new_ap(request):
    """ Creation d'une ap. Cree en meme temps l'interface et la machine
486 487
    associée. Vue complexe. Appelle successivement les 3 models forms
    adaptés : machine, interface, domain et switch"""
488
    ap = AddAccessPointForm(
489 490 491
        request.POST or None,
        user=request.user
    )
492
    interface = AddInterfaceForm(
493 494 495 496 497 498
        request.POST or None,
        user=request.user
    )
    domain = DomainForm(
        request.POST or None,
        )
499
    if ap.is_valid() and interface.is_valid():
500 501 502 503 504
        user = AssoOption.get_cached_value('utilisateur_asso')
        if not user:
            messages.error(request, "L'user association n'existe pas encore,\
            veuillez le créer ou le linker dans preferences")
            return redirect(reverse('topologie:index'))
505
        new_ap = ap.save(commit=False)
506 507 508
        new_ap.user = user
        new_interface = interface.save(commit=False)
        domain.instance.interface_parent = new_interface
509 510
        if domain.is_valid():
            new_domain_instance = domain.save(commit=False)
511
            new_ap.save()
512
            new_interface.machine = new_ap
513
            new_interface.save()
514
            new_domain_instance.interface_parent = new_interface
515
            new_domain_instance.save()
516
            messages.success(request, "La borne a été créé")
517
            return redirect(reverse('topologie:index-ap'))
518
    i_mbf_param = generate_ipv4_mbf_param(interface, False)
519
    return form({
520 521
        'topoform': interface,
        'machineform': ap,
522
        'domainform': domain,
523 524 525
        'i_mbf_param': i_mbf_param,
        'device' : 'wifi ap',
        }, 'topologie/topo_more.html', request)
526 527 528


@login_required
529
@can_edit(AccessPoint)
530
def edit_ap(request, ap, accesspointid):
531 532
    """ Edition d'un switch. Permet de chambre nombre de ports,
    place dans le stack, interface et machine associée"""
533
    interface_form = EditInterfaceForm(
534 535
        request.POST or None,
        user=request.user,
536
        instance=ap.interface_set.first()
537
    )
538
    ap_form = EditAccessPointForm(
539 540
        request.POST or None,
        user=request.user,
541
        instance=ap
542 543 544
    )
    domain_form = DomainForm(
        request.POST or None,
545
        instance=ap.interface_set.first().domain
546
        )
547
    if ap_form.is_valid() and interface_form.is_valid():
548 549 550 551
        user = AssoOption.get_cached_value('utilisateur_asso')
        if not user:
            messages.error(request, "L'user association n'existe pas encore,\
            veuillez le créer ou le linker dans preferences")
552 553
            return redirect(reverse('topologie:index-ap'))
        new_ap = ap_form.save(commit=False)
554
        new_interface = interface_form.save(commit=False)
555
        new_domain = domain_form.save(commit=False)
556 557 558
        new_ap.save()
        new_interface.save()
        new_domain.save()
559
        messages.success(request, "La borne a été modifiée")
560
        return redirect(reverse('topologie:index-ap'))
561
    i_mbf_param = generate_ipv4_mbf_param(interface_form, False )
562
    return form({
563 564
        'topoform': interface_form,
        'machineform': ap_form,
565
        'domainform': domain_form,
566 567 568
        'i_mbf_param': i_mbf_param,
        'device' : 'wifi ap',
        }, 'topologie/topo_more.html', request)
569 570
    

chirac's avatar
chirac committed
571
@login_required
572
@can_create(Room)
chirac's avatar
chirac committed
573
def new_room(request):
574
    """Nouvelle chambre """
chirac's avatar
chirac committed
575 576
    room = EditRoomForm(request.POST or None)
    if room.is_valid():
577
        room.save()
chirac's avatar
chirac committed
578
        messages.success(request, "La chambre a été créé")
579
        return redirect(reverse('topologie:index-room'))
580
    return form({'topoform': room, 'action_name' : 'Ajouter'}, 'topologie/topo.html', request)
chirac's avatar
chirac committed
581

chirac's avatar
chirac committed
582 583

@login_required
584
@can_edit(Room)
585
def edit_room(request, room, roomid):
586
    """ Edition numero et details de la chambre"""
chirac's avatar
chirac committed
587 588
    room = EditRoomForm(request.POST or None, instance=room)
    if room.is_valid():
589
        room.save()
chirac's avatar
chirac committed
590
        messages.success(request, "La chambre a bien été modifiée")
591
        return redirect(reverse('topologie:index-room'))
592
    return form({'topoform': room, 'action_name' : 'Editer'}, 'topologie/topo.html', request)
chirac's avatar
chirac committed
593

chirac's avatar
chirac committed
594 595

@login_required
596
@can_delete(Room)
597
def del_room(request, room, roomid):
598
    """ Suppression d'un chambre"""
chirac's avatar
chirac committed
599
    if request.method == "POST":
600
        try:
601 602
            room.delete()
            messages.success(request, "La chambre/prise a été détruite")
603
        except ProtectedError:
chirac's avatar
chirac committed
604 605
            messages.error(request, "La chambre %s est affectée à un autre objet,\
                impossible de la supprimer (switch ou user)" % room)
606
        return redirect(reverse('topologie:index-room'))
chirac's avatar
chirac committed
607 608 609 610
    return form({
        'objet': room,
        'objet_name': 'Chambre'
        }, 'topologie/delete.html', request)
611 612 613


@login_required
614
@can_create(ModelSwitch)
615 616 617 618
def new_model_switch(request):
    """Nouveau modèle de switch"""
    model_switch = EditModelSwitchForm(request.POST or None)
    if model_switch.is_valid():
619
        model_switch.save()
620
        messages.success(request, "Le modèle a été créé")
621
        return redirect(reverse('topologie:index-model-switch'))
622
    return form({'topoform': model_switch, 'action_name' : 'Ajouter'}, 'topologie/topo.html', request)
623 624 625


@login_required
626
@can_edit(ModelSwitch)
627
def edit_model_switch(request, model_switch, modelswitchid):
628
    """ Edition d'un modèle de switch"""
629

630 631
    model_switch = EditModelSwitchForm(request.POST or None, instance=model_switch)
    if model_switch.is_valid():
632
        model_switch.save()
633
        messages.success(request, "Le modèle a bien été modifié")
634
        return redirect(reverse('topologie:index-model-switch'))
635
    return form({'topoform': model_switch, 'action_name' : 'Editer'}, 'topologie/topo.html', request)
636 637 638


@login_required
639
@can_delete(ModelSwitch)
640
def del_model_switch(request, model_switch, modelswitchid):
641 642 643
    """ Suppression d'un modèle de switch"""
    if request.method == "POST":
        try:
644 645
            model_switch.delete()
            messages.success(request, "Le modèle a été détruit")
646 647 648
        except ProtectedError:
            messages.error(request, "Le modèle %s est affectée à un autre objet,\
                impossible de la supprimer (switch ou user)" % model_switch)
649
        return redirect(reverse('topologie:index-model-switch'))
650 651 652 653 654 655 656
    return form({
        'objet': model_switch,
        'objet_name': 'Modèle de switch'
        }, 'topologie/delete.html', request)


@login_required
657
@can_create(ConstructorSwitch)
658 659 660 661
def new_constructor_switch(request):
    """Nouveau constructeur de switch"""
    constructor_switch = EditConstructorSwitchForm(request.POST or None)
    if constructor_switch.is_valid():
662
        constructor_switch.save()
663
        messages.success(request, "Le constructeur a été créé")
664
        return redirect(reverse('topologie:index-model-switch'))
665
    return form({'topoform': constructor_switch, 'action_name' : 'Ajouter'}, 'topologie/topo.html', request)
666 667 668


@login_required
669
@can_edit(ConstructorSwitch)
670
def edit_constructor_switch(request, constructor_switch, constructorswitchid):
671
    """ Edition d'un constructeur de switch"""
672

673 674
    constructor_switch = EditConstructorSwitchForm(request.POST or None, instance=constructor_switch)
    if constructor_switch.is_valid():
675
        constructor_switch.save()
676
        messages.success(request, "Le modèle a bien été modifié")
677
        return redirect(reverse('topologie:index-model-switch'))
678
    return form({'topoform': constructor_switch, 'action_name' : 'Editer'}, 'topologie/topo.html', request)
679 680 681


@login_required
682
@can_delete(ConstructorSwitch)
683
def del_constructor_switch(request, constructor_switch, constructorswitchid):
684 685 686
    """ Suppression d'un constructeur de switch"""
    if request.method == "POST":
        try:
687 688
            constructor_switch.delete()
            messages.success(request, "Le constructeur a été détruit")
689 690 691
        except ProtectedError:
            messages.error(request, "Le constructeur %s est affecté à un autre objet,\
                impossible de la supprimer (switch ou user)" % constructor_switch)
692
        return redirect(reverse('topologie:index-model-switch'))
693 694 695 696
    return form({
        'objet': constructor_switch,
        'objet_name': 'Constructeur de switch'
        }, 'topologie/delete.html', request)