2017-01-15 23:01:18 +00:00
|
|
|
# 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.
|
2017-10-13 23:43:01 +00:00
|
|
|
"""
|
|
|
|
Page des vues de l'application topologie
|
2017-01-15 23:01:18 +00:00
|
|
|
|
2017-10-13 23:43:01 +00:00
|
|
|
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
|
|
|
|
"""
|
2017-09-10 23:29:24 +00:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
2017-10-26 15:58:41 +00:00
|
|
|
from django.urls import reverse
|
2016-07-06 19:50:15 +00:00
|
|
|
from django.shortcuts import render, redirect
|
|
|
|
from django.contrib import messages
|
2016-07-09 02:12:09 +00:00
|
|
|
from django.contrib.auth.decorators import login_required, permission_required
|
2016-07-06 21:29:31 +00:00
|
|
|
from django.db import IntegrityError
|
2016-07-21 00:30:36 +00:00
|
|
|
from django.db import transaction
|
2017-08-17 22:17:56 +00:00
|
|
|
from django.db.models import ProtectedError
|
2017-10-26 21:29:26 +00:00
|
|
|
from django.core.exceptions import ValidationError
|
2016-07-27 01:36:28 +00:00
|
|
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
2016-07-21 00:30:36 +00:00
|
|
|
from reversion import revisions as reversion
|
2016-12-11 16:24:04 +00:00
|
|
|
from reversion.models import Version
|
2016-07-06 19:50:15 +00:00
|
|
|
|
2017-10-26 03:07:11 +00:00
|
|
|
from topologie.models import (
|
|
|
|
Switch,
|
|
|
|
Port,
|
|
|
|
Room,
|
|
|
|
Stack,
|
|
|
|
ModelSwitch,
|
|
|
|
ConstructorSwitch
|
|
|
|
)
|
2017-10-13 23:43:01 +00:00
|
|
|
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
|
2017-10-26 03:07:11 +00:00
|
|
|
from topologie.forms import (
|
|
|
|
AddPortForm,
|
|
|
|
EditRoomForm,
|
|
|
|
StackForm,
|
|
|
|
EditModelSwitchForm,
|
2017-10-26 19:38:55 +00:00
|
|
|
EditConstructorSwitchForm,
|
|
|
|
CreatePortsForm
|
2017-10-26 03:07:11 +00:00
|
|
|
)
|
2016-07-06 19:50:15 +00:00
|
|
|
from users.views import form
|
2017-12-09 04:49:29 +00:00
|
|
|
from re2o.utils import (
|
|
|
|
SortTable,
|
|
|
|
can_create,
|
|
|
|
can_edit,
|
|
|
|
can_delete,
|
2017-12-27 22:07:05 +00:00
|
|
|
can_view,
|
|
|
|
can_view_all,
|
2017-12-09 04:49:29 +00:00
|
|
|
)
|
2017-10-26 03:07:11 +00:00
|
|
|
from machines.forms import (
|
|
|
|
DomainForm,
|
|
|
|
NewMachineForm,
|
|
|
|
EditMachineForm,
|
|
|
|
EditInterfaceForm,
|
|
|
|
AddInterfaceForm
|
|
|
|
)
|
2017-10-14 13:27:56 +00:00
|
|
|
from machines.views import generate_ipv4_mbf_param
|
2017-08-25 02:35:49 +00:00
|
|
|
from preferences.models import AssoOption, GeneralOption
|
2016-10-27 17:45:31 +00:00
|
|
|
|
2016-07-27 01:36:28 +00:00
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
@login_required
|
2017-12-27 22:07:05 +00:00
|
|
|
@can_view_all(Switch)
|
2016-07-06 19:50:15 +00:00
|
|
|
def index(request):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Vue d'affichage de tous les swicthes"""
|
2017-10-22 00:33:44 +00:00
|
|
|
switch_list = Switch.objects\
|
2017-10-13 23:43:01 +00:00
|
|
|
.select_related('switch_interface__domain__extension')\
|
|
|
|
.select_related('switch_interface__ipv4')\
|
|
|
|
.select_related('switch_interface__domain')\
|
|
|
|
.select_related('stack')
|
2017-10-22 00:33:44 +00:00
|
|
|
switch_list = SortTable.sort(
|
|
|
|
switch_list,
|
|
|
|
request.GET.get('col'),
|
|
|
|
request.GET.get('order'),
|
|
|
|
SortTable.TOPOLOGIE_INDEX
|
|
|
|
)
|
2017-10-26 16:48:09 +00:00
|
|
|
options, _created = GeneralOption.objects.get_or_create()
|
|
|
|
pagination_number = options.pagination_number
|
|
|
|
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)
|
2017-10-13 23:43:01 +00:00
|
|
|
return render(request, 'topologie/index.html', {
|
|
|
|
'switch_list': switch_list
|
|
|
|
})
|
|
|
|
|
2016-07-06 19:50:15 +00:00
|
|
|
|
2016-07-21 00:30:36 +00:00
|
|
|
@login_required
|
|
|
|
@permission_required('cableur')
|
2017-10-13 23:43:01 +00:00
|
|
|
def history(request, object_name, object_id):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Vue générique pour afficher l'historique complet d'un objet"""
|
2017-10-13 23:43:01 +00:00
|
|
|
if object_name == 'switch':
|
2016-07-21 00:30:36 +00:00
|
|
|
try:
|
2017-10-13 23:43:01 +00:00
|
|
|
object_instance = Switch.objects.get(pk=object_id)
|
2016-07-21 00:30:36 +00:00
|
|
|
except Switch.DoesNotExist:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "Switch inexistant")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-13 23:43:01 +00:00
|
|
|
elif object_name == 'port':
|
2016-07-21 00:30:36 +00:00
|
|
|
try:
|
2017-10-13 23:43:01 +00:00
|
|
|
object_instance = Port.objects.get(pk=object_id)
|
2016-07-21 00:30:36 +00:00
|
|
|
except Port.DoesNotExist:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "Port inexistant")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-13 23:43:01 +00:00
|
|
|
elif object_name == 'room':
|
2016-07-21 00:30:36 +00:00
|
|
|
try:
|
2017-10-13 23:43:01 +00:00
|
|
|
object_instance = Room.objects.get(pk=object_id)
|
2016-07-21 00:30:36 +00:00
|
|
|
except Room.DoesNotExist:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "Chambre inexistante")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-13 23:43:01 +00:00
|
|
|
elif object_name == 'stack':
|
2017-08-17 22:17:56 +00:00
|
|
|
try:
|
2017-10-13 23:43:01 +00:00
|
|
|
object_instance = Stack.objects.get(pk=object_id)
|
2017-08-17 22:17:56 +00:00
|
|
|
except Room.DoesNotExist:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "Stack inexistante")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-26 03:07:11 +00:00
|
|
|
elif object_name == 'model_switch':
|
|
|
|
try:
|
|
|
|
object_instance = ModelSwitch.objects.get(pk=object_id)
|
|
|
|
except ModelSwitch.DoesNotExist:
|
|
|
|
messages.error(request, "SwitchModel inexistant")
|
2017-10-26 21:35:26 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-26 03:07:11 +00:00
|
|
|
elif object_name == 'constructor_switch':
|
|
|
|
try:
|
|
|
|
object_instance = ConstructorSwitch.objects.get(pk=object_id)
|
|
|
|
except ConstructorSwitch.DoesNotExist:
|
|
|
|
messages.error(request, "SwitchConstructor inexistant")
|
2017-10-26 21:35:26 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2016-07-21 00:30:36 +00:00
|
|
|
else:
|
|
|
|
messages.error(request, "Objet inconnu")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-13 23:43:01 +00:00
|
|
|
options, _created = GeneralOption.objects.get_or_create()
|
2017-06-25 23:29:34 +00:00
|
|
|
pagination_number = options.pagination_number
|
2016-12-11 16:24:04 +00:00
|
|
|
reversions = Version.objects.get_for_object(object_instance)
|
2017-06-25 23:29:34 +00:00
|
|
|
paginator = Paginator(reversions, pagination_number)
|
2016-07-27 01:36:28 +00:00
|
|
|
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)
|
2017-10-13 23:43:01 +00:00
|
|
|
return render(request, 're2o/history.html', {
|
|
|
|
'reversions': reversions,
|
|
|
|
'object': object_instance
|
|
|
|
})
|
|
|
|
|
2016-07-21 00:30:36 +00:00
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
@login_required
|
2017-12-27 22:07:05 +00:00
|
|
|
@can_view_all(Port)
|
|
|
|
@can_view(Switch)
|
|
|
|
def index_port(request, switch, switch_id):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Affichage de l'ensemble des ports reliés à un switch particulier"""
|
2017-10-13 23:43:01 +00:00
|
|
|
port_list = Port.objects.filter(switch=switch)\
|
|
|
|
.select_related('room')\
|
|
|
|
.select_related('machine_interface__domain__extension')\
|
2017-10-18 01:50:33 +00:00
|
|
|
.select_related('machine_interface__machine__user')\
|
2017-10-26 19:29:34 +00:00
|
|
|
.select_related(
|
|
|
|
'related__switch__switch_interface__domain__extension'
|
|
|
|
)\
|
2017-10-22 00:33:44 +00:00
|
|
|
.select_related('switch')
|
|
|
|
port_list = SortTable.sort(
|
|
|
|
port_list,
|
|
|
|
request.GET.get('col'),
|
|
|
|
request.GET.get('order'),
|
|
|
|
SortTable.TOPOLOGIE_INDEX_PORT
|
|
|
|
)
|
2017-10-13 23:43:01 +00:00
|
|
|
return render(request, 'topologie/index_p.html', {
|
|
|
|
'port_list': port_list,
|
|
|
|
'id_switch': switch_id,
|
|
|
|
'nom_switch': switch
|
|
|
|
})
|
|
|
|
|
2016-07-06 21:29:31 +00:00
|
|
|
|
2016-07-19 00:30:52 +00:00
|
|
|
@login_required
|
2017-12-27 22:07:05 +00:00
|
|
|
@can_view_all(Room)
|
2016-07-19 00:30:52 +00:00
|
|
|
def index_room(request):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Affichage de l'ensemble des chambres"""
|
2017-10-22 01:37:27 +00:00
|
|
|
room_list = Room.objects
|
2017-10-22 00:33:44 +00:00
|
|
|
room_list = SortTable.sort(
|
|
|
|
room_list,
|
|
|
|
request.GET.get('col'),
|
|
|
|
request.GET.get('order'),
|
|
|
|
SortTable.TOPOLOGIE_INDEX_ROOM
|
|
|
|
)
|
2017-10-13 23:43:01 +00:00
|
|
|
options, _created = GeneralOption.objects.get_or_create()
|
2017-09-02 13:40:44 +00:00
|
|
|
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)
|
2017-10-13 23:43:01 +00:00
|
|
|
return render(request, 'topologie/index_room.html', {
|
|
|
|
'room_list': room_list
|
|
|
|
})
|
|
|
|
|
2016-07-19 00:30:52 +00:00
|
|
|
|
2017-08-17 22:17:56 +00:00
|
|
|
@login_required
|
2017-12-27 22:07:05 +00:00
|
|
|
@can_view_all(Stack)
|
2017-08-17 22:17:56 +00:00
|
|
|
def index_stack(request):
|
2017-10-13 23:43:01 +00:00
|
|
|
"""Affichage de la liste des stacks (affiche l'ensemble des switches)"""
|
2017-10-22 00:33:44 +00:00
|
|
|
stack_list = Stack.objects\
|
2017-10-13 23:43:01 +00:00
|
|
|
.prefetch_related('switch_set__switch_interface__domain__extension')
|
2017-10-22 00:33:44 +00:00
|
|
|
stack_list = SortTable.sort(
|
|
|
|
stack_list,
|
|
|
|
request.GET.get('col'),
|
|
|
|
request.GET.get('order'),
|
|
|
|
SortTable.TOPOLOGIE_INDEX_STACK
|
|
|
|
)
|
2017-10-13 23:43:01 +00:00
|
|
|
return render(request, 'topologie/index_stack.html', {
|
|
|
|
'stack_list': stack_list
|
|
|
|
})
|
2017-08-17 22:17:56 +00:00
|
|
|
|
|
|
|
|
2017-10-26 03:07:11 +00:00
|
|
|
@login_required
|
2017-12-27 22:07:05 +00:00
|
|
|
@can_view_all(ModelSwitch)
|
|
|
|
@can_view_all(ConstructorSwitch)
|
2017-10-26 03:07:11 +00:00
|
|
|
def index_model_switch(request):
|
|
|
|
""" Affichage de l'ensemble des modèles de switches"""
|
|
|
|
model_switch_list = ModelSwitch.objects
|
|
|
|
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,
|
|
|
|
})
|
|
|
|
|
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(Port)
|
2016-07-06 21:29:31 +00:00
|
|
|
def new_port(request, switch_id):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Nouveau port"""
|
2016-07-06 21:29:31 +00:00
|
|
|
try:
|
|
|
|
switch = Switch.objects.get(pk=switch_id)
|
|
|
|
except Switch.DoesNotExist:
|
|
|
|
messages.error(request, u"Switch inexistant")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2016-07-06 21:29:31 +00:00
|
|
|
port = AddPortForm(request.POST or None)
|
|
|
|
if port.is_valid():
|
|
|
|
port = port.save(commit=False)
|
|
|
|
port.switch = switch
|
|
|
|
try:
|
2016-07-21 00:30:36 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
port.save()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Création")
|
2016-07-06 21:29:31 +00:00
|
|
|
messages.success(request, "Port ajouté")
|
|
|
|
except IntegrityError:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "Ce port existe déjà")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse(
|
|
|
|
'topologie:index-port',
|
|
|
|
kwargs={'switch_id':switch_id}
|
|
|
|
))
|
2017-12-15 00:49:05 +00:00
|
|
|
return form({'id_switch': switch_id,'topoform': port}, 'topologie/topo.html', request)
|
2017-10-13 23:43:01 +00:00
|
|
|
|
2016-07-06 19:50:15 +00:00
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(Port)
|
|
|
|
def edit_port(request, port_object, port_id):
|
2017-10-13 23:43:01 +00:00
|
|
|
""" Edition d'un port. Permet de changer le switch parent et
|
|
|
|
l'affectation du port"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2016-11-18 23:34:42 +00:00
|
|
|
port = EditPortForm(request.POST or None, instance=port_object)
|
2016-07-06 19:50:15 +00:00
|
|
|
if port.is_valid():
|
2016-07-21 00:30:36 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
port.save()
|
|
|
|
reversion.set_user(request.user)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in port.changed_data
|
|
|
|
))
|
2016-07-06 19:50:15 +00:00
|
|
|
messages.success(request, "Le port a bien été modifié")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse(
|
|
|
|
'topologie:index-port',
|
|
|
|
kwargs={'switch_id': str(port_object.switch.id)}
|
|
|
|
))
|
2017-12-15 00:49:05 +00:00
|
|
|
return form({'id_switch': str(port_object.switch.id), 'topoform': port}, 'topologie/topo.html', request)
|
2017-10-13 23:43:01 +00:00
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
|
2017-08-17 22:17:56 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_delete(Port)
|
|
|
|
def del_port(request, port, port_id):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Supprime le port"""
|
2017-09-04 02:45:36 +00:00
|
|
|
if request.method == "POST":
|
|
|
|
try:
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
port.delete()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Destruction")
|
2017-10-26 09:08:54 +00:00
|
|
|
messages.success(request, "Le port a été détruit")
|
2017-09-04 02:45:36 +00:00
|
|
|
except ProtectedError:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "Le port %s est affecté à un autre objet,\
|
|
|
|
impossible de le supprimer" % port)
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse(
|
|
|
|
'topologie:index-port',
|
2017-10-26 22:11:18 +00:00
|
|
|
kwargs={'switch_id':str(port.switch.id)}
|
2017-10-26 15:58:41 +00:00
|
|
|
))
|
2017-10-13 23:43:01 +00:00
|
|
|
return form({'objet': port}, 'topologie/delete.html', request)
|
|
|
|
|
2017-09-04 02:45:36 +00:00
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(Stack)
|
2017-08-17 22:17:56 +00:00
|
|
|
def new_stack(request):
|
2017-10-13 23:43:01 +00:00
|
|
|
"""Ajoute un nouveau stack : stack_id_min, max, et nombre de switches"""
|
2017-08-17 22:17:56 +00:00
|
|
|
stack = StackForm(request.POST or None)
|
2017-10-13 23:43:01 +00:00
|
|
|
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)
|
2017-08-17 22:17:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(Stack)
|
|
|
|
def edit_stack(request, stack, stack_id):
|
2017-10-13 23:43:01 +00:00
|
|
|
"""Edition d'un stack (nombre de switches, nom...)"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2017-08-17 22:17:56 +00:00
|
|
|
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)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment(
|
|
|
|
"Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in stack.changed_data
|
|
|
|
)
|
|
|
|
)
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index-stack'))
|
2017-10-13 23:43:01 +00:00
|
|
|
return form({'topoform': stack}, 'topologie/topo.html', request)
|
|
|
|
|
2017-08-17 22:17:56 +00:00
|
|
|
|
2017-08-18 12:20:51 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_delete(Stack)
|
|
|
|
def del_stack(request, stack, stack_id):
|
2017-10-13 23:43:01 +00:00
|
|
|
"""Supprime un stack"""
|
2017-08-18 12:20:51 +00:00
|
|
|
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:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "La stack %s est affectée à un autre\
|
|
|
|
objet, impossible de la supprimer" % stack)
|
2017-12-09 13:57:48 +00:00
|
|
|
return redirect(reverse('topologie:index-stack'))
|
2017-10-13 23:43:01 +00:00
|
|
|
return form({'objet': stack}, 'topologie/delete.html', request)
|
|
|
|
|
2017-08-18 12:20:51 +00:00
|
|
|
|
2017-08-18 23:16:51 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(Stack)
|
|
|
|
def edit_switchs_stack(request, stack, stack_id):
|
2017-10-13 23:43:01 +00:00
|
|
|
"""Permet d'éditer la liste des switches dans une stack et l'ajouter"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2017-08-18 23:16:51 +00:00
|
|
|
if request.method == "POST":
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
context = {'stack': stack}
|
|
|
|
context['switchs_stack'] = stack.switchs_set.all()
|
|
|
|
context['switchs_autres'] = Switch.object.filter(stack=None)
|
|
|
|
|
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(Switch)
|
2016-07-06 21:29:31 +00:00
|
|
|
def new_switch(request):
|
2017-10-13 23:43:01 +00:00
|
|
|
""" 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"""
|
2016-10-27 17:45:31 +00:00
|
|
|
switch = NewSwitchForm(request.POST or None)
|
|
|
|
machine = NewMachineForm(request.POST or None)
|
2017-10-13 23:43:01 +00:00
|
|
|
interface = AddInterfaceForm(
|
|
|
|
request.POST or None,
|
|
|
|
infra=request.user.has_perms(('infra',))
|
|
|
|
)
|
2017-10-18 00:27:42 +00:00
|
|
|
domain = DomainForm(
|
2017-10-13 23:43:01 +00:00
|
|
|
request.POST or None,
|
|
|
|
)
|
2016-10-27 17:45:31 +00:00
|
|
|
if switch.is_valid() and machine.is_valid() and interface.is_valid():
|
2017-10-13 23:43:01 +00:00
|
|
|
options, _created = AssoOption.objects.get_or_create()
|
2017-08-25 02:35:49 +00:00
|
|
|
user = options.utilisateur_asso
|
|
|
|
if not user:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "L'user association n'existe pas encore,\
|
|
|
|
veuillez le créer ou le linker dans preferences")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2016-10-27 17:45:31 +00:00
|
|
|
new_machine = machine.save(commit=False)
|
|
|
|
new_machine.user = user
|
|
|
|
new_interface = interface.save(commit=False)
|
2017-10-13 23:43:01 +00:00
|
|
|
new_switch_instance = switch.save(commit=False)
|
|
|
|
new_domain_instance = domain.save(commit=False)
|
2017-07-21 03:06:53 +00:00
|
|
|
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")
|
2017-10-13 23:43:01 +00:00
|
|
|
new_domain_instance.interface_parent = new_interface
|
2017-07-21 03:06:53 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
2017-10-13 23:43:01 +00:00
|
|
|
new_domain_instance.save()
|
2017-07-21 03:06:53 +00:00
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Création")
|
2017-10-13 23:43:01 +00:00
|
|
|
new_switch_instance.switch_interface = new_interface
|
2017-07-21 03:06:53 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
2017-10-13 23:43:01 +00:00
|
|
|
new_switch_instance.save()
|
2017-07-21 03:06:53 +00:00
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Création")
|
2017-10-12 09:57:16 +00:00
|
|
|
messages.success(request, "Le switch a été créé")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-26 21:35:26 +00:00
|
|
|
i_mbf_param = generate_ipv4_mbf_param( interface, False)
|
2017-10-13 23:56:14 +00:00
|
|
|
return form({
|
|
|
|
'topoform': switch,
|
|
|
|
'machineform': machine,
|
|
|
|
'interfaceform': interface,
|
|
|
|
'domainform': domain,
|
2017-10-15 15:27:13 +00:00
|
|
|
'i_mbf_param': i_mbf_param
|
2017-10-13 23:56:14 +00:00
|
|
|
}, 'topologie/switch.html', request)
|
|
|
|
|
2016-07-06 21:29:31 +00:00
|
|
|
|
2017-10-26 08:41:48 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(Port)
|
2017-10-26 08:41:48 +00:00
|
|
|
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/")
|
2017-10-26 21:29:26 +00:00
|
|
|
|
2017-10-26 08:41:48 +00:00
|
|
|
s_begin = s_end = 0
|
2017-10-26 09:05:27 +00:00
|
|
|
nb_ports = switch.ports.count()
|
|
|
|
if nb_ports > 0:
|
2017-10-26 09:51:41 +00:00
|
|
|
ports = switch.ports.order_by('port').values('port')
|
|
|
|
s_begin = ports.first().get('port')
|
|
|
|
s_end = ports.last().get('port')
|
2017-10-26 21:29:26 +00:00
|
|
|
|
2017-10-26 08:41:48 +00:00
|
|
|
port_form = CreatePortsForm(
|
|
|
|
request.POST or None,
|
2017-10-26 19:29:34 +00:00
|
|
|
initial={'begin': s_begin, 'end': s_end}
|
2017-10-26 08:41:48 +00:00
|
|
|
)
|
2017-10-26 21:29:26 +00:00
|
|
|
|
2017-10-26 08:41:48 +00:00
|
|
|
if port_form.is_valid():
|
|
|
|
begin = port_form.cleaned_data['begin']
|
|
|
|
end = port_form.cleaned_data['end']
|
2017-10-26 21:29:26 +00:00
|
|
|
try:
|
|
|
|
switch.create_ports(begin, end)
|
|
|
|
messages.success(request, "Ports créés.")
|
|
|
|
except ValidationError as e:
|
|
|
|
messages.error(request, ''.join(e))
|
|
|
|
|
2017-10-26 09:14:16 +00:00
|
|
|
return redirect("/topologie/switch/" + str(switch.id))
|
2017-10-26 08:41:48 +00:00
|
|
|
|
2017-12-15 00:49:05 +00:00
|
|
|
return form({'id_switch': switch_id, 'topoform': port_form}, 'topologie/switch.html', request)
|
2017-10-26 19:29:34 +00:00
|
|
|
|
2016-07-06 21:29:31 +00:00
|
|
|
|
2016-07-08 10:35:53 +00:00
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(Switch)
|
|
|
|
def edit_switch(request, switch, switch_id):
|
2017-10-13 23:43:01 +00:00
|
|
|
""" Edition d'un switch. Permet de chambre nombre de ports,
|
|
|
|
place dans le stack, interface et machine associée"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2016-10-28 00:09:24 +00:00
|
|
|
switch_form = EditSwitchForm(request.POST or None, instance=switch)
|
2017-10-13 23:43:01 +00:00
|
|
|
machine_form = EditMachineForm(
|
|
|
|
request.POST or None,
|
|
|
|
instance=switch.switch_interface.machine
|
|
|
|
)
|
|
|
|
interface_form = EditInterfaceForm(
|
|
|
|
request.POST or None,
|
|
|
|
instance=switch.switch_interface
|
|
|
|
)
|
2017-10-18 00:27:42 +00:00
|
|
|
domain_form = DomainForm(
|
2017-10-13 23:43:01 +00:00
|
|
|
request.POST or None,
|
|
|
|
instance=switch.switch_interface.domain
|
|
|
|
)
|
|
|
|
if switch_form.is_valid() and machine_form.is_valid()\
|
|
|
|
and interface_form.is_valid():
|
2016-10-28 00:09:24 +00:00
|
|
|
new_interface = interface_form.save(commit=False)
|
|
|
|
new_machine = machine_form.save(commit=False)
|
2017-10-13 23:43:01 +00:00
|
|
|
new_switch_instance = switch_form.save(commit=False)
|
2016-12-24 19:32:36 +00:00
|
|
|
new_domain = domain_form.save(commit=False)
|
2017-07-21 03:06:53 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
new_machine.save()
|
|
|
|
reversion.set_user(request.user)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment(
|
|
|
|
"Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in machine_form.changed_data
|
|
|
|
)
|
|
|
|
)
|
2017-07-21 03:06:53 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
new_interface.save()
|
|
|
|
reversion.set_user(request.user)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in interface_form.changed_data)
|
|
|
|
)
|
2017-07-21 03:06:53 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
new_domain.save()
|
|
|
|
reversion.set_user(request.user)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in domain_form.changed_data)
|
|
|
|
)
|
2017-07-21 03:06:53 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
2017-10-13 23:43:01 +00:00
|
|
|
new_switch_instance.save()
|
2017-07-21 03:06:53 +00:00
|
|
|
reversion.set_user(request.user)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in switch_form.changed_data)
|
|
|
|
)
|
2017-07-21 03:06:53 +00:00
|
|
|
messages.success(request, "Le switch a bien été modifié")
|
2017-11-15 10:37:10 +00:00
|
|
|
return redirect(reverse('topologie:index'))
|
2017-10-15 15:27:13 +00:00
|
|
|
i_mbf_param = generate_ipv4_mbf_param( interface_form, False )
|
2017-10-13 23:56:14 +00:00
|
|
|
return form({
|
2017-12-15 00:49:05 +00:00
|
|
|
'id_switch': switch_id,
|
2017-10-13 23:56:14 +00:00
|
|
|
'topoform': switch_form,
|
|
|
|
'machineform': machine_form,
|
|
|
|
'interfaceform': interface_form,
|
|
|
|
'domainform': domain_form,
|
2017-10-15 15:27:13 +00:00
|
|
|
'i_mbf_param': i_mbf_param
|
2017-10-13 23:56:14 +00:00
|
|
|
}, 'topologie/switch.html', request)
|
|
|
|
|
2016-07-19 00:30:52 +00:00
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(Room)
|
2016-07-19 00:30:52 +00:00
|
|
|
def new_room(request):
|
2017-10-06 02:17:45 +00:00
|
|
|
"""Nouvelle chambre """
|
2016-07-19 00:30:52 +00:00
|
|
|
room = EditRoomForm(request.POST or None)
|
|
|
|
if room.is_valid():
|
2016-07-21 00:30:36 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
room.save()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Création")
|
2016-07-19 00:30:52 +00:00
|
|
|
messages.success(request, "La chambre a été créé")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index-room'))
|
2017-10-13 23:43:01 +00:00
|
|
|
return form({'topoform': room}, 'topologie/topo.html', request)
|
|
|
|
|
2016-07-19 00:30:52 +00:00
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(Room)
|
|
|
|
def edit_room(request, room, room_id):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Edition numero et details de la chambre"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2016-07-19 00:30:52 +00:00
|
|
|
room = EditRoomForm(request.POST or None, instance=room)
|
|
|
|
if room.is_valid():
|
2016-07-21 00:30:36 +00:00
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
room.save()
|
|
|
|
reversion.set_user(request.user)
|
2017-10-13 23:43:01 +00:00
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in room.changed_data)
|
|
|
|
)
|
2016-07-19 00:30:52 +00:00
|
|
|
messages.success(request, "La chambre a bien été modifiée")
|
2017-10-26 15:58:41 +00:00
|
|
|
return redirect(reverse('topologie:index-room'))
|
2017-10-13 23:43:01 +00:00
|
|
|
return form({'topoform': room}, 'topologie/topo.html', request)
|
|
|
|
|
2016-07-19 00:30:52 +00:00
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_delete(Room)
|
|
|
|
def del_room(request, room, room_id):
|
2017-10-06 02:17:45 +00:00
|
|
|
""" Suppression d'un chambre"""
|
2016-07-19 00:30:52 +00:00
|
|
|
if request.method == "POST":
|
2017-08-17 22:17:56 +00:00
|
|
|
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:
|
2017-10-13 23:43:01 +00:00
|
|
|
messages.error(request, "La chambre %s est affectée à un autre objet,\
|
|
|
|
impossible de la supprimer (switch ou user)" % room)
|
2017-12-09 13:57:48 +00:00
|
|
|
return redirect(reverse('topologie:index-room'))
|
2017-10-13 23:43:01 +00:00
|
|
|
return form({
|
|
|
|
'objet': room,
|
|
|
|
'objet_name': 'Chambre'
|
|
|
|
}, 'topologie/delete.html', request)
|
2017-10-26 03:07:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(ModelSwitch)
|
2017-10-26 03:07:11 +00:00
|
|
|
def new_model_switch(request):
|
|
|
|
"""Nouveau modèle de switch"""
|
|
|
|
model_switch = EditModelSwitchForm(request.POST or None)
|
|
|
|
if model_switch.is_valid():
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
model_switch.save()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Création")
|
|
|
|
messages.success(request, "Le modèle a été créé")
|
|
|
|
return redirect("/topologie/index_model_switch/")
|
|
|
|
return form({'topoform': model_switch}, 'topologie/topo.html', request)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(ModelSwitch)
|
|
|
|
def edit_model_switch(request, model_switch, model_switch_id):
|
2017-10-26 03:07:11 +00:00
|
|
|
""" Edition d'un modèle de switch"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2017-10-26 03:07:11 +00:00
|
|
|
model_switch = EditModelSwitchForm(request.POST or None, instance=model_switch)
|
|
|
|
if model_switch.is_valid():
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
model_switch.save()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in model_switch.changed_data)
|
|
|
|
)
|
|
|
|
messages.success(request, "Le modèle a bien été modifié")
|
|
|
|
return redirect("/topologie/index_model_switch/")
|
|
|
|
return form({'topoform': model_switch}, 'topologie/topo.html', request)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_delete(ModelSwitch)
|
2017-10-26 03:07:11 +00:00
|
|
|
def del_model_switch(request, model_switch_id):
|
|
|
|
""" Suppression d'un modèle de switch"""
|
|
|
|
if request.method == "POST":
|
|
|
|
try:
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
model_switch.delete()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Destruction")
|
|
|
|
messages.success(request, "Le modèle a été détruit")
|
|
|
|
except ProtectedError:
|
|
|
|
messages.error(request, "Le modèle %s est affectée à un autre objet,\
|
|
|
|
impossible de la supprimer (switch ou user)" % model_switch)
|
|
|
|
return redirect("/topologie/index_model_switch/")
|
|
|
|
return form({
|
|
|
|
'objet': model_switch,
|
|
|
|
'objet_name': 'Modèle de switch'
|
|
|
|
}, 'topologie/delete.html', request)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_create(ConstructorSwitch)
|
2017-10-26 03:07:11 +00:00
|
|
|
def new_constructor_switch(request):
|
|
|
|
"""Nouveau constructeur de switch"""
|
|
|
|
constructor_switch = EditConstructorSwitchForm(request.POST or None)
|
|
|
|
if constructor_switch.is_valid():
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
constructor_switch.save()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Création")
|
|
|
|
messages.success(request, "Le constructeur a été créé")
|
|
|
|
return redirect("/topologie/index_model_switch/")
|
|
|
|
return form({'topoform': constructor_switch}, 'topologie/topo.html', request)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_edit(ConstructorSwitch)
|
|
|
|
def edit_constructor_switch(request, constructor_switch, constructor_switch_id):
|
2017-10-26 03:07:11 +00:00
|
|
|
""" Edition d'un constructeur de switch"""
|
2017-12-09 04:49:29 +00:00
|
|
|
|
2017-10-26 03:07:11 +00:00
|
|
|
constructor_switch = EditConstructorSwitchForm(request.POST or None, instance=constructor_switch)
|
|
|
|
if constructor_switch.is_valid():
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
constructor_switch.save()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
|
|
|
field for field in constructor_switch.changed_data)
|
|
|
|
)
|
|
|
|
messages.success(request, "Le modèle a bien été modifié")
|
|
|
|
return redirect("/topologie/index_model_switch/")
|
|
|
|
return form({'topoform': constructor_switch}, 'topologie/topo.html', request)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
2017-12-09 04:49:29 +00:00
|
|
|
@can_delete(ConstructorSwitch)
|
2017-10-26 03:07:11 +00:00
|
|
|
def del_constructor_switch(request, constructor_switch_id):
|
|
|
|
""" Suppression d'un constructeur de switch"""
|
|
|
|
if request.method == "POST":
|
|
|
|
try:
|
|
|
|
with transaction.atomic(), reversion.create_revision():
|
|
|
|
constructor_switch.delete()
|
|
|
|
reversion.set_user(request.user)
|
|
|
|
reversion.set_comment("Destruction")
|
|
|
|
messages.success(request, "Le constructeur a été détruit")
|
|
|
|
except ProtectedError:
|
|
|
|
messages.error(request, "Le constructeur %s est affecté à un autre objet,\
|
|
|
|
impossible de la supprimer (switch ou user)" % constructor_switch)
|
|
|
|
return redirect("/topologie/index_model_switch/")
|
|
|
|
return form({
|
|
|
|
'objet': constructor_switch,
|
|
|
|
'objet_name': 'Constructeur de switch'
|
|
|
|
}, 'topologie/delete.html', request)
|