views.py 22.7 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 39
import itertools

Dalahro's avatar
Dalahro committed
40 41
from django.shortcuts import render, redirect
from django.contrib import messages
42
from django.contrib.auth.decorators import login_required, permission_required
Dalahro's avatar
Dalahro committed
43
from django.db import IntegrityError
44
from django.db import transaction
45
from django.db.models import ProtectedError
chirac's avatar
chirac committed
46
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
47
from reversion import revisions as reversion
root's avatar
root committed
48
from reversion.models import Version
Dalahro's avatar
Dalahro committed
49

50
from topologie.models import Switch, Port, Room, Stack
chirac's avatar
chirac committed
51 52
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
from topologie.forms import AddPortForm, EditRoomForm, StackForm
53
from topologie.forms import CreatePortsForm
Dalahro's avatar
Dalahro committed
54
from users.views import form
55
from re2o.utils import SortTable
56 57 58 59 60 61 62
from machines.forms import (
    DomainForm,
    NewMachineForm,
    EditMachineForm,
    EditInterfaceForm,
    AddInterfaceForm
)
63
from machines.views import generate_ipv4_mbf_param
64
from preferences.models import AssoOption, GeneralOption
65

chirac's avatar
chirac committed
66

chirac's avatar
chirac committed
67
@login_required
chirac's avatar
chirac committed
68
@permission_required('cableur')
Dalahro's avatar
Dalahro committed
69
def index(request):
70
    """ Vue d'affichage de tous les swicthes"""
71
    switch_list = Switch.objects\
chirac's avatar
chirac committed
72 73 74 75
        .select_related('switch_interface__domain__extension')\
        .select_related('switch_interface__ipv4')\
        .select_related('switch_interface__domain')\
        .select_related('stack')
76 77 78 79 80 81
    switch_list = SortTable.sort(
        switch_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX
    )
chirac's avatar
chirac committed
82 83 84 85
    return render(request, 'topologie/index.html', {
        'switch_list': switch_list
        })

Dalahro's avatar
Dalahro committed
86

87 88
@login_required
@permission_required('cableur')
chirac's avatar
chirac committed
89
def history(request, object_name, object_id):
90
    """ Vue générique pour afficher l'historique complet d'un objet"""
chirac's avatar
chirac committed
91
    if object_name == 'switch':
92
        try:
chirac's avatar
chirac committed
93
            object_instance = Switch.objects.get(pk=object_id)
94
        except Switch.DoesNotExist:
chirac's avatar
chirac committed
95 96 97
            messages.error(request, "Switch inexistant")
            return redirect("/topologie/")
    elif object_name == 'port':
98
        try:
chirac's avatar
chirac committed
99
            object_instance = Port.objects.get(pk=object_id)
100
        except Port.DoesNotExist:
chirac's avatar
chirac committed
101 102 103
            messages.error(request, "Port inexistant")
            return redirect("/topologie/")
    elif object_name == 'room':
104
        try:
chirac's avatar
chirac committed
105
            object_instance = Room.objects.get(pk=object_id)
106
        except Room.DoesNotExist:
chirac's avatar
chirac committed
107 108 109
            messages.error(request, "Chambre inexistante")
            return redirect("/topologie/")
    elif object_name == 'stack':
110
        try:
chirac's avatar
chirac committed
111
            object_instance = Stack.objects.get(pk=object_id)
112
        except Room.DoesNotExist:
chirac's avatar
chirac committed
113 114
            messages.error(request, "Stack inexistante")
            return redirect("/topologie/")
115 116 117
    else:
        messages.error(request, "Objet  inconnu")
        return redirect("/topologie/")
chirac's avatar
chirac committed
118
    options, _created = GeneralOption.objects.get_or_create()
119
    pagination_number = options.pagination_number
root's avatar
root committed
120
    reversions = Version.objects.get_for_object(object_instance)
121
    paginator = Paginator(reversions, pagination_number)
chirac's avatar
chirac committed
122 123 124 125 126 127 128 129 130
    page = request.GET.get('page')
    try:
        reversions = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        reversions = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        reversions = paginator.page(paginator.num_pages)
chirac's avatar
chirac committed
131 132 133 134 135
    return render(request, 're2o/history.html', {
        'reversions': reversions,
        'object': object_instance
        })

136

chirac's avatar
chirac committed
137
@login_required
chirac's avatar
chirac committed
138
@permission_required('cableur')
Dalahro's avatar
Dalahro committed
139
def index_port(request, switch_id):
140
    """ Affichage de l'ensemble des ports reliés à un switch particulier"""
Dalahro's avatar
Dalahro committed
141 142 143 144 145
    try:
        switch = Switch.objects.get(pk=switch_id)
    except Switch.DoesNotExist:
        messages.error(request, u"Switch inexistant")
        return redirect("/topologie/")
chirac's avatar
chirac committed
146 147 148
    port_list = Port.objects.filter(switch=switch)\
        .select_related('room')\
        .select_related('machine_interface__domain__extension')\
149
        .select_related('machine_interface__machine__user')\
150 151 152
        .select_related(
            'related__switch__switch_interface__domain__extension'
        )\
153 154 155 156 157 158 159
        .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
160 161 162 163 164 165
    return render(request, 'topologie/index_p.html', {
        'port_list': port_list,
        'id_switch': switch_id,
        'nom_switch': switch
        })

Dalahro's avatar
Dalahro committed
166

chirac's avatar
chirac committed
167 168 169
@login_required
@permission_required('cableur')
def index_room(request):
170
    """ Affichage de l'ensemble des chambres"""
171
    room_list = Room.objects
172 173 174 175 176 177
    room_list = SortTable.sort(
        room_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_ROOM
    )
chirac's avatar
chirac committed
178
    options, _created = GeneralOption.objects.get_or_create()
Gabriel Detraz's avatar
Gabriel Detraz committed
179 180 181 182 183 184 185 186 187 188 189
    pagination_number = options.pagination_number
    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
190 191 192 193
    return render(request, 'topologie/index_room.html', {
        'room_list': room_list
        })

chirac's avatar
chirac committed
194

195 196 197
@login_required
@permission_required('infra')
def index_stack(request):
chirac's avatar
chirac committed
198
    """Affichage de la liste des stacks (affiche l'ensemble des switches)"""
199
    stack_list = Stack.objects\
chirac's avatar
chirac committed
200
        .prefetch_related('switch_set__switch_interface__domain__extension')
201 202 203 204 205 206
    stack_list = SortTable.sort(
        stack_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.TOPOLOGIE_INDEX_STACK
    )
chirac's avatar
chirac committed
207 208 209
    return render(request, 'topologie/index_stack.html', {
        'stack_list': stack_list
        })
210 211


chirac's avatar
chirac committed
212
@login_required
213
@permission_required('infra')
Dalahro's avatar
Dalahro committed
214
def new_port(request, switch_id):
215
    """ Nouveau port"""
Dalahro's avatar
Dalahro committed
216 217 218 219 220 221 222 223 224 225
    try:
        switch = Switch.objects.get(pk=switch_id)
    except Switch.DoesNotExist:
        messages.error(request, u"Switch inexistant")
        return redirect("/topologie/")
    port = AddPortForm(request.POST or None)
    if port.is_valid():
        port = port.save(commit=False)
        port.switch = switch
        try:
226 227 228 229
            with transaction.atomic(), reversion.create_revision():
                port.save()
                reversion.set_user(request.user)
                reversion.set_comment("Création")
Dalahro's avatar
Dalahro committed
230 231
            messages.success(request, "Port ajouté")
        except IntegrityError:
chirac's avatar
chirac committed
232
            messages.error(request, "Ce port existe déjà")
Dalahro's avatar
Dalahro committed
233
        return redirect("/topologie/switch/" + switch_id)
chirac's avatar
chirac committed
234 235
    return form({'topoform': port}, 'topologie/topo.html', request)

Dalahro's avatar
Dalahro committed
236

chirac's avatar
chirac committed
237
@login_required
238
@permission_required('infra')
Dalahro's avatar
Dalahro committed
239
def edit_port(request, port_id):
chirac's avatar
chirac committed
240 241
    """ Edition d'un port. Permet de changer le switch parent et
    l'affectation du port"""
Dalahro's avatar
Dalahro committed
242
    try:
chirac's avatar
chirac committed
243 244 245 246 247 248 249
        port_object = Port.objects\
            .select_related('switch__switch_interface__domain__extension')\
            .select_related('machine_interface__domain__extension')\
            .select_related('machine_interface__switch')\
            .select_related('room')\
            .select_related('related')\
            .get(pk=port_id)
Dalahro's avatar
Dalahro committed
250 251 252
    except Port.DoesNotExist:
        messages.error(request, u"Port inexistant")
        return redirect("/topologie/")
253
    port = EditPortForm(request.POST or None, instance=port_object)
Dalahro's avatar
Dalahro committed
254
    if port.is_valid():
255 256 257
        with transaction.atomic(), reversion.create_revision():
            port.save()
            reversion.set_user(request.user)
chirac's avatar
chirac committed
258 259 260
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in port.changed_data
                ))
Dalahro's avatar
Dalahro committed
261
        messages.success(request, "Le port a bien été modifié")
262
        return redirect("/topologie/switch/" + str(port_object.switch.id))
chirac's avatar
chirac committed
263 264
    return form({'topoform': port}, 'topologie/topo.html', request)

chirac's avatar
chirac committed
265

266
@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
267
@permission_required('infra')
chirac's avatar
chirac committed
268
def del_port(request, port_id):
269
    """ Supprime le port"""
Gabriel Detraz's avatar
Gabriel Detraz committed
270 271 272 273 274 275 276 277 278 279 280
    try:
        port = Port.objects.get(pk=port_id)
    except Port.DoesNotExist:
        messages.error(request, u"Port inexistant")
        return redirect('/topologie/')
    if request.method == "POST":
        try:
            with transaction.atomic(), reversion.create_revision():
                port.delete()
                reversion.set_user(request.user)
                reversion.set_comment("Destruction")
Levy--Falk Hugo's avatar
Levy--Falk Hugo committed
281
                messages.success(request, "Le port a été détruit")
Gabriel Detraz's avatar
Gabriel Detraz committed
282
        except ProtectedError:
chirac's avatar
chirac committed
283 284
            messages.error(request, "Le port %s est affecté à un autre objet,\
                impossible de le supprimer" % port)
Gabriel Detraz's avatar
Gabriel Detraz committed
285
        return redirect('/topologie/switch/' + str(port.switch.id))
chirac's avatar
chirac committed
286 287
    return form({'objet': port}, 'topologie/delete.html', request)

Gabriel Detraz's avatar
Gabriel Detraz committed
288 289

@login_required
290 291
@permission_required('infra')
def new_stack(request):
chirac's avatar
chirac committed
292
    """Ajoute un nouveau stack : stack_id_min, max, et nombre de switches"""
293
    stack = StackForm(request.POST or None)
chirac's avatar
chirac committed
294 295 296 297 298 299 300
    if stack.is_valid():
        with transaction.atomic(), reversion.create_revision():
            stack.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        messages.success(request, "Stack crée")
    return form({'topoform': stack}, 'topologie/topo.html', request)
301 302 303 304


@login_required
@permission_required('infra')
chirac's avatar
chirac committed
305 306
def edit_stack(request, stack_id):
    """Edition d'un stack (nombre de switches, nom...)"""
307 308 309 310
    try:
        stack = Stack.objects.get(pk=stack_id)
    except Stack.DoesNotExist:
        messages.error(request, u"Stack inexistante")
311
        return redirect('/topologie/index_stack/')
312 313 314 315 316
    stack = StackForm(request.POST or None, instance=stack)
    if stack.is_valid():
        with transaction.atomic(), reversion.create_revision():
            stack.save()
            reversion.set_user(request.user)
chirac's avatar
chirac committed
317 318 319 320 321
            reversion.set_comment(
                "Champs modifié(s) : %s" % ', '.join(
                    field for field in stack.changed_data
                    )
                )
322
        return redirect('/topologie/index_stack')
chirac's avatar
chirac committed
323 324
    return form({'topoform': stack}, 'topologie/topo.html', request)

325

326 327
@login_required
@permission_required('infra')
chirac's avatar
chirac committed
328 329
def del_stack(request, stack_id):
    """Supprime un stack"""
330 331 332 333 334 335 336 337 338 339 340 341 342
    try:
        stack = Stack.objects.get(pk=stack_id)
    except Stack.DoesNotExist:
        messages.error(request, u"Stack inexistante")
        return redirect('/topologie/index_stack')
    if request.method == "POST":
        try:
            with transaction.atomic(), reversion.create_revision():
                stack.delete()
                reversion.set_user(request.user)
                reversion.set_comment("Destruction")
                messages.success(request, "La stack a eté détruite")
        except ProtectedError:
chirac's avatar
chirac committed
343 344
            messages.error(request, "La stack %s est affectée à un autre\
                objet, impossible de la supprimer" % stack)
345
        return redirect('/topologie/index_stack')
chirac's avatar
chirac committed
346 347
    return form({'objet': stack}, 'topologie/delete.html', request)

348

349 350
@login_required
@permission_required('infra')
chirac's avatar
chirac committed
351 352
def edit_switchs_stack(request, stack_id):
    """Permet d'éditer la liste des switches dans une stack et l'ajouter"""
353 354 355 356 357 358 359 360 361 362 363 364 365
    try:
        stack = Stack.objects.get(pk=stack_id)
    except Stack.DoesNotExist:
        messages.error(request, u"Stack inexistante")
        return redirect('/topologie/index_stack')
    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
366
@login_required
367
@permission_required('infra')
Dalahro's avatar
Dalahro committed
368
def new_switch(request):
chirac's avatar
chirac committed
369 370 371
    """ 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"""
372 373
    switch = NewSwitchForm(request.POST or None)
    machine = NewMachineForm(request.POST or None)
chirac's avatar
chirac committed
374 375 376 377
    interface = AddInterfaceForm(
        request.POST or None,
        infra=request.user.has_perms(('infra',))
        )
378
    domain = DomainForm(
chirac's avatar
chirac committed
379 380
        request.POST or None,
        )
381
    if switch.is_valid() and machine.is_valid() and interface.is_valid():
chirac's avatar
chirac committed
382
        options, _created = AssoOption.objects.get_or_create()
383 384
        user = options.utilisateur_asso
        if not user:
chirac's avatar
chirac committed
385 386
            messages.error(request, "L'user association n'existe pas encore,\
            veuillez le créer ou le linker dans preferences")
387 388 389 390
            return redirect("/topologie/")
        new_machine = machine.save(commit=False)
        new_machine.user = user
        new_interface = interface.save(commit=False)
chirac's avatar
chirac committed
391 392
        new_switch_instance = switch.save(commit=False)
        new_domain_instance = domain.save(commit=False)
393 394 395 396 397 398 399 400 401
        with transaction.atomic(), reversion.create_revision():
            new_machine.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        new_interface.machine = new_machine
        with transaction.atomic(), reversion.create_revision():
            new_interface.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
chirac's avatar
chirac committed
402
        new_domain_instance.interface_parent = new_interface
403
        with transaction.atomic(), reversion.create_revision():
chirac's avatar
chirac committed
404
            new_domain_instance.save()
405 406
            reversion.set_user(request.user)
            reversion.set_comment("Création")
chirac's avatar
chirac committed
407
        new_switch_instance.switch_interface = new_interface
408
        with transaction.atomic(), reversion.create_revision():
chirac's avatar
chirac committed
409
            new_switch_instance.save()
410 411
            reversion.set_user(request.user)
            reversion.set_comment("Création")
412
        messages.success(request, "Le switch a été créé")
413
        return redirect("/topologie/")
414
    i_mbf_param = generate_ipv4_mbf_param(interface, False)
chirac's avatar
chirac committed
415 416 417 418 419
    return form({
        'topoform': switch,
        'machineform': machine,
        'interfaceform': interface,
        'domainform': domain,
420
        'i_mbf_param': i_mbf_param
chirac's avatar
chirac committed
421 422
        }, 'topologie/switch.html', request)

423

424 425 426 427 428 429 430 431 432 433 434
@login_required
@permission_required('infra')
def create_ports(request, switch_id):
    """ Création d'une liste de ports pour un switch."""
    try:
        switch = Switch.objects.get(pk=switch_id)
    except Switch.DoesNotExist:
        messages.error(request, u"Switch inexistant")
        return redirect("/topologie/")

    s_begin = s_end = 0
435 436
    nb_ports = switch.ports.count()
    if nb_ports > 0:
Levy--Falk Hugo's avatar
Levy--Falk Hugo committed
437 438 439
        ports = switch.ports.order_by('port').values('port')
        s_begin = ports.first().get('port')
        s_end = ports.last().get('port')
440 441 442

    port_form = CreatePortsForm(
        request.POST or None,
443
        initial={'begin': s_begin, 'end': s_end}
444 445 446 447 448 449
    )
    if port_form.is_valid():
        begin = port_form.cleaned_data['begin']
        end = port_form.cleaned_data['end']
        if end < begin:
            messages.error(request, "Port de fin inférieur au port de début !")
450
            return redirect("/topologie/switch/" + str(switch.id))
451 452
        if end - begin > switch.number:
            messages.error(request, "Ce switch ne peut avoir autant de ports.")
453
            return redirect("/topologie/switch/" + str(switch.id))
454

455 456 457 458 459 460
        begin_range = range(begin, s_begin)
        end_range = range(s_end+1, end+1)
        for i in itertools.chain(begin_range, end_range):
            port = Port()
            port.switch = switch
            port.port = i
461 462
            try:
                with transaction.atomic(), reversion.create_revision():
463
                    port.save()
464 465 466 467 468
                    reversion.set_user(request.user)
                    reversion.set_comment("Création")
                messages.success(request, "Création du port %d" % i)
            except IntegrityError:
                messages.error(request, "Création d'un port existant.")
469
        return redirect("/topologie/switch/" + str(switch.id))
470

471 472
    return form({'topoform': port_form}, 'topologie/switch.html', request)

Dalahro's avatar
Dalahro committed
473

chirac's avatar
chirac committed
474
@login_required
475
@permission_required('infra')
Dalahro's avatar
Dalahro committed
476
def edit_switch(request, switch_id):
chirac's avatar
chirac committed
477 478
    """ Edition d'un switch. Permet de chambre nombre de ports,
    place dans le stack, interface et machine associée"""
Dalahro's avatar
Dalahro committed
479 480 481 482 483
    try:
        switch = Switch.objects.get(pk=switch_id)
    except Switch.DoesNotExist:
        messages.error(request, u"Switch inexistant")
        return redirect("/topologie/")
484
    switch_form = EditSwitchForm(request.POST or None, instance=switch)
chirac's avatar
chirac committed
485 486 487 488 489 490 491 492
    machine_form = EditMachineForm(
        request.POST or None,
        instance=switch.switch_interface.machine
        )
    interface_form = EditInterfaceForm(
        request.POST or None,
        instance=switch.switch_interface
        )
493
    domain_form = DomainForm(
chirac's avatar
chirac committed
494 495 496 497 498
        request.POST or None,
        instance=switch.switch_interface.domain
        )
    if switch_form.is_valid() and machine_form.is_valid()\
            and interface_form.is_valid():
499 500
        new_interface = interface_form.save(commit=False)
        new_machine = machine_form.save(commit=False)
chirac's avatar
chirac committed
501
        new_switch_instance = switch_form.save(commit=False)
chirac's avatar
chirac committed
502
        new_domain = domain_form.save(commit=False)
503 504 505
        with transaction.atomic(), reversion.create_revision():
            new_machine.save()
            reversion.set_user(request.user)
chirac's avatar
chirac committed
506 507 508 509 510
            reversion.set_comment(
                "Champs modifié(s) : %s" % ', '.join(
                    field for field in machine_form.changed_data
                    )
                )
511 512 513
        with transaction.atomic(), reversion.create_revision():
            new_interface.save()
            reversion.set_user(request.user)
chirac's avatar
chirac committed
514 515 516
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in interface_form.changed_data)
                                 )
517 518 519
        with transaction.atomic(), reversion.create_revision():
            new_domain.save()
            reversion.set_user(request.user)
chirac's avatar
chirac committed
520 521 522
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in domain_form.changed_data)
                                 )
523
        with transaction.atomic(), reversion.create_revision():
chirac's avatar
chirac committed
524
            new_switch_instance.save()
525
            reversion.set_user(request.user)
chirac's avatar
chirac committed
526 527 528
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in switch_form.changed_data)
                                 )
529 530
        messages.success(request, "Le switch a bien été modifié")
        return redirect("/topologie/")
531
    i_mbf_param = generate_ipv4_mbf_param(interface_form, False)
chirac's avatar
chirac committed
532 533 534 535 536
    return form({
        'topoform': switch_form,
        'machineform': machine_form,
        'interfaceform': interface_form,
        'domainform': domain_form,
537
        'i_mbf_param': i_mbf_param
chirac's avatar
chirac committed
538 539
        }, 'topologie/switch.html', request)

chirac's avatar
chirac committed
540 541 542 543

@login_required
@permission_required('infra')
def new_room(request):
544
    """Nouvelle chambre """
chirac's avatar
chirac committed
545 546
    room = EditRoomForm(request.POST or None)
    if room.is_valid():
547 548 549 550
        with transaction.atomic(), reversion.create_revision():
            room.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
chirac's avatar
chirac committed
551 552
        messages.success(request, "La chambre a été créé")
        return redirect("/topologie/index_room/")
chirac's avatar
chirac committed
553 554
    return form({'topoform': room}, 'topologie/topo.html', request)

chirac's avatar
chirac committed
555 556 557 558

@login_required
@permission_required('infra')
def edit_room(request, room_id):
559
    """ Edition numero et details de la chambre"""
chirac's avatar
chirac committed
560 561 562 563 564 565 566
    try:
        room = Room.objects.get(pk=room_id)
    except Room.DoesNotExist:
        messages.error(request, u"Chambre inexistante")
        return redirect("/topologie/index_room/")
    room = EditRoomForm(request.POST or None, instance=room)
    if room.is_valid():
567 568 569
        with transaction.atomic(), reversion.create_revision():
            room.save()
            reversion.set_user(request.user)
chirac's avatar
chirac committed
570 571 572
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in room.changed_data)
                                 )
chirac's avatar
chirac committed
573 574
        messages.success(request, "La chambre a bien été modifiée")
        return redirect("/topologie/index_room/")
chirac's avatar
chirac committed
575 576
    return form({'topoform': room}, 'topologie/topo.html', request)

chirac's avatar
chirac committed
577 578 579 580

@login_required
@permission_required('infra')
def del_room(request, room_id):
581
    """ Suppression d'un chambre"""
chirac's avatar
chirac committed
582 583 584
    try:
        room = Room.objects.get(pk=room_id)
    except Room.DoesNotExist:
chirac's avatar
chirac committed
585
        messages.error(request, u"Chambre inexistante")
chirac's avatar
chirac committed
586 587
        return redirect("/topologie/index_room/")
    if request.method == "POST":
588 589 590 591 592 593 594
        try:
            with transaction.atomic(), reversion.create_revision():
                room.delete()
                reversion.set_user(request.user)
                reversion.set_comment("Destruction")
                messages.success(request, "La chambre/prise a été détruite")
        except ProtectedError:
chirac's avatar
chirac committed
595 596
            messages.error(request, "La chambre %s est affectée à un autre objet,\
                impossible de la supprimer (switch ou user)" % room)
chirac's avatar
chirac committed
597
        return redirect("/topologie/index_room/")
chirac's avatar
chirac committed
598 599 600 601
    return form({
        'objet': room,
        'objet_name': 'Chambre'
        }, 'topologie/delete.html', request)