diff --git a/re2o/utils.py b/re2o/utils.py index 739dd200..2560e6c2 100644 --- a/re2o/utils.py +++ b/re2o/utils.py @@ -216,6 +216,15 @@ class SortTable: 'stack_id': ['stack_id'], 'default': ['stack_id'], } + TOPOLOGIE_INDEX_MODEL_SWITCH = { + 'model_switch_name': ['reference'], + 'model_switch__contructor' : ['constructor__name'], + 'default': ['reference'], + } + TOPOLOGIE_INDEX_CONSTRUCTOR_SWITCH = { + 'room_name': ['name'], + 'default': ['name'], + } LOGS_INDEX = { 'sum_date': ['revision__date_created'], 'default': ['-revision__date_created'], diff --git a/topologie/admin.py b/topologie/admin.py index bfc2a393..a4591222 100644 --- a/topologie/admin.py +++ b/topologie/admin.py @@ -29,7 +29,7 @@ from __future__ import unicode_literals from django.contrib import admin from reversion.admin import VersionAdmin -from .models import Port, Room, Switch, Stack +from .models import Port, Room, Switch, Stack, ModelSwitch, ConstructorSwitch class StackAdmin(VersionAdmin): @@ -52,7 +52,19 @@ class RoomAdmin(VersionAdmin): pass +class ModelSwitchAdmin(VersionAdmin): + """Administration d'un modèle de switch""" + pass + + +class ConstructorSwitchAdmin(VersionAdmin): + """Administration d'un constructeur d'un switch""" + pass + + admin.site.register(Port, PortAdmin) admin.site.register(Room, RoomAdmin) admin.site.register(Switch, SwitchAdmin) admin.site.register(Stack, StackAdmin) +admin.site.register(ModelSwitch, ModelSwitchAdmin) +admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin) diff --git a/topologie/forms.py b/topologie/forms.py index c8e39d6a..39759695 100644 --- a/topologie/forms.py +++ b/topologie/forms.py @@ -33,8 +33,9 @@ NewSwitchForm) from __future__ import unicode_literals from machines.models import Interface -from django.forms import ModelForm -from .models import Port, Switch, Room, Stack +from django import forms +from django.forms import ModelForm, Form +from .models import Port, Switch, Room, Stack, ModelSwitch, ConstructorSwitch class PortForm(ModelForm): @@ -125,7 +126,8 @@ class NewSwitchForm(ModelForm): def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) super(NewSwitchForm, self).__init__(*args, prefix=prefix, **kwargs) - + self.fields['location'].label = 'Localisation' + self.fields['number'].label = 'Nombre de ports' class EditRoomForm(ModelForm): """Permet d'éediter le nom et commentaire d'une prise murale""" @@ -136,3 +138,31 @@ class EditRoomForm(ModelForm): def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) super(EditRoomForm, self).__init__(*args, prefix=prefix, **kwargs) + + +class CreatePortsForm(Form): + """Permet de créer une liste de ports pour un switch.""" + begin = forms.IntegerField(label="Début :", min_value=0) + end = forms.IntegerField(label="Fin :", min_value=0) + + +class EditModelSwitchForm(ModelForm): + """Permet d'éediter un modèle de switch : nom et constructeur""" + class Meta: + model = ModelSwitch + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(EditModelSwitchForm, self).__init__(*args, prefix=prefix, **kwargs) + + +class EditConstructorSwitchForm(ModelForm): + """Permet d'éediter le nom d'un constructeur""" + class Meta: + model = ConstructorSwitch + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(EditConstructorSwitchForm, self).__init__(*args, prefix=prefix, **kwargs) diff --git a/topologie/migrations/0032_auto_20171026_0338.py b/topologie/migrations/0032_auto_20171026_0338.py new file mode 100644 index 00000000..37548306 --- /dev/null +++ b/topologie/migrations/0032_auto_20171026_0338.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-10-26 01:38 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('topologie', '0031_auto_20171015_2033'), + ] + + operations = [ + migrations.CreateModel( + name='ConstructorSwitch', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name='ModelSwitch', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('reference', models.CharField(max_length=255)), + ('constructor', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='topologie.ConstructorSwitch')), + ], + ), + migrations.AddField( + model_name='switch', + name='model', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='topologie.ModelSwitch'), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index adcc7a57..fca4a3be 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -37,10 +37,15 @@ la prise from __future__ import unicode_literals +import itertools + from django.db import models from django.db.models.signals import post_delete from django.dispatch import receiver from django.core.exceptions import ValidationError +from django.db import IntegrityError +from django.db import transaction +from reversion import revisions as reversion class Stack(models.Model): @@ -93,12 +98,18 @@ class Switch(models.Model): number = models.PositiveIntegerField() details = models.CharField(max_length=255, blank=True) stack = models.ForeignKey( - Stack, + 'topologie.Stack', blank=True, null=True, on_delete=models.SET_NULL ) stack_member_id = models.PositiveIntegerField(blank=True, null=True) + model = models.ForeignKey( + 'topologie.ModelSwitch', + blank=True, + null=True, + on_delete=models.SET_NULL + ) class Meta: unique_together = ('stack', 'stack_member_id') @@ -119,6 +130,52 @@ class Switch(models.Model): else: raise ValidationError({'stack_member_id': "L'id dans la stack\ ne peut être nul"}) + def create_ports(self, begin, end): + """ Crée les ports de begin à end si les valeurs données sont cohérentes. """ + + s_begin = s_end = 0 + nb_ports = self.ports.count() + if nb_ports > 0: + ports = self.ports.order_by('port').values('port') + s_begin = ports.first().get('port') + s_end = ports.last().get('port') + + if end < begin: + raise ValidationError("Port de fin inférieur au port de début !") + if end - begin > self.number: + raise ValidationError("Ce switch ne peut avoir autant de ports.") + 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 = self + port.port = i + try: + with transaction.atomic(), reversion.create_revision(): + port.save() + reversion.set_comment("Création") + except IntegrityError: + ValidationError("Création d'un port existant.") + + +class ModelSwitch(models.Model): + """Un modèle (au sens constructeur) de switch""" + reference = models.CharField(max_length=255) + constructor = models.ForeignKey( + 'topologie.ConstructorSwitch', + on_delete=models.PROTECT + ) + + def __str__(self): + return str(self.constructor) + ' ' + str(self.reference) + + +class ConstructorSwitch(models.Model): + """Un constructeur de switch""" + name = models.CharField(max_length=255) + + def __str__(self): + return str(self.name) class Port(models.Model): diff --git a/topologie/templates/topologie/aff_constructor_switch.html b/topologie/templates/topologie/aff_constructor_switch.html new file mode 100644 index 00000000..02002f6c --- /dev/null +++ b/topologie/templates/topologie/aff_constructor_switch.html @@ -0,0 +1,54 @@ +{% comment %} +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. +{% endcomment %} + +{% if constructor_switch_list.paginator %} +{% include "pagination.html" with list=constructor_switch_list %} +{% endif %} + + + + + + + + + {% for constructor_switch in constructor_switch_list %} + + + + + {% endfor %} +
{% include "buttons/sort.html" with prefix='constructor-switch' col='name' text='Constructeur' %}
{{constructor_switch}} + + + + {% if is_infra %} + + + + + + + {% endif %} +
diff --git a/topologie/templates/topologie/aff_model_switch.html b/topologie/templates/topologie/aff_model_switch.html new file mode 100644 index 00000000..2e84fb69 --- /dev/null +++ b/topologie/templates/topologie/aff_model_switch.html @@ -0,0 +1,56 @@ +{% comment %} +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. +{% endcomment %} + +{% if model_switch_list.paginator %} +{% include "pagination.html" with list=model_switch_list %} +{% endif %} + + + + + + + + + + {% for model_switch in model_switch_list %} + + + + + + {% endfor %} +
{% include "buttons/sort.html" with prefix='model-switch' col='reference' text='Référence' %}{% include "buttons/sort.html" with prefix='model-switch' col='constructor' text='Constructeur' %}
{{model_switch.reference}}{{model_switch.constructor}} + + + + {% if is_infra %} + + + + + + + {% endif %} +
diff --git a/topologie/templates/topologie/aff_switch.html b/topologie/templates/topologie/aff_switch.html index c0d6c55f..25f466e8 100644 --- a/topologie/templates/topologie/aff_switch.html +++ b/topologie/templates/topologie/aff_switch.html @@ -22,6 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. {% endcomment %} +{% if switch_list.paginator %} +{% include "pagination.html" with list=switch_list %} +{% endif %} + @@ -30,7 +34,8 @@ with this program; if not, write to the Free Software Foundation, Inc., - + + @@ -47,12 +52,14 @@ with this program; if not, write to the Free Software Foundation, Inc., + diff --git a/topologie/templates/topologie/index.html b/topologie/templates/topologie/index.html index 72b522d0..6b17b6de 100644 --- a/topologie/templates/topologie/index.html +++ b/topologie/templates/topologie/index.html @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

Switchs

{% if is_infra %} Ajouter un switch +
{% endif %} {% include "topologie/aff_switch.html" with switch_list=switch_list %}
diff --git a/topologie/templates/topologie/index_model_switch.html b/topologie/templates/topologie/index_model_switch.html new file mode 100644 index 00000000..784b5ea6 --- /dev/null +++ b/topologie/templates/topologie/index_model_switch.html @@ -0,0 +1,46 @@ +{% extends "topologie/sidebar.html" %} +{% comment %} +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. +{% endcomment %} + +{% load bootstrap3 %} + +{% block title %}Modèles de switches{% endblock %} + +{% block content %} +

Modèles de switches

+{% if is_infra %} + Ajouter un modèle +
+{% endif %} +{% include "topologie/aff_model_switch.html" with model_switch_list=model_switch_list %} +

Constructeurs de switches

+{% if is_infra %} + Ajouter un constructeur +
+{% endif %} +{% include "topologie/aff_constructor_switch.html" with constructor_switch_list=constructor_switch_list %} +
+
+
+{% endblock %} diff --git a/topologie/templates/topologie/index_p.html b/topologie/templates/topologie/index_p.html index 84159659..3f9356f2 100644 --- a/topologie/templates/topologie/index_p.html +++ b/topologie/templates/topologie/index_p.html @@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if is_infra %} Editer Ajouter un port + Ajouter des ports {% endif %} {% include "topologie/aff_port.html" with port_list=port_list %}
diff --git a/topologie/templates/topologie/sidebar.html b/topologie/templates/topologie/sidebar.html index 833af2e3..a2d42896 100644 --- a/topologie/templates/topologie/sidebar.html +++ b/topologie/templates/topologie/sidebar.html @@ -37,4 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc., Stacks + + + Modèles switches et constructeurs + {% endblock %} diff --git a/topologie/templates/topologie/switch.html b/topologie/templates/topologie/switch.html index e87570c4..1753161e 100644 --- a/topologie/templates/topologie/switch.html +++ b/topologie/templates/topologie/switch.html @@ -47,12 +47,15 @@ with this program; if not, write to the Free Software Foundation, Inc., {% csrf_token %} {% if topoform %} +

Réglage spécifiques du switch

{% massive_bootstrap_form topoform 'switch_interface' %} {% endif %} {% if machineform %} +

Réglages généraux de la machine associée au switch

{% massive_bootstrap_form machineform 'user' %} {% endif %} {% if interfaceform %} +

Réglages généraux de l'interface associée au switch

{% if i_mbf_param %} {% massive_bootstrap_form interfaceform 'ipv4,machine' mbf_param=i_mbf_param %} {% else %} @@ -60,6 +63,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% endif %} {% if domainform %} +

Nom de la machine

{% bootstrap_form domainform %} {% endif %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="ok" %} diff --git a/topologie/urls.py b/topologie/urls.py index 77a78b97..752ebcc5 100644 --- a/topologie/urls.py +++ b/topologie/urls.py @@ -35,6 +35,9 @@ from . import views urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^new_switch/$', views.new_switch, name='new-switch'), + url(r'^create_ports/(?P[0-9]+)$', + views.create_ports, + name='create-ports'), url(r'^index_room/$', views.index_room, name='index-room'), url(r'^new_room/$', views.new_room, name='new-room'), url(r'^edit_room/(?P[0-9]+)$', views.edit_room, name='edit-room'), @@ -54,6 +57,12 @@ urlpatterns = [ url(r'^history/(?Pstack)/(?P[0-9]+)$', views.history, name='history'), + url(r'^history/(?Pmodel_switch)/(?P[0-9]+)$', + views.history, + name='history'), + url(r'^history/(?Pconstructor_switch)/(?P[0-9]+)$', + views.history, + name='history'), url(r'^edit_port/(?P[0-9]+)$', views.edit_port, name='edit-port'), url(r'^new_port/(?P[0-9]+)$', views.new_port, name='new-port'), url(r'^del_port/(?P[0-9]+)$', views.del_port, name='del-port'), @@ -68,4 +77,32 @@ urlpatterns = [ url(r'^del_stack/(?P[0-9]+)$', views.del_stack, name='del-stack'), + url(r'^index_model_switch/$', + views.index_model_switch, + name='index-model-switch' + ), + url(r'^index_model_switch/$', + views.index_model_switch, + name='index-model-switch' + ), + url(r'^new_model_switch/$', + views.new_model_switch, + name='new-model-switch' + ), + url(r'^edit_model_switch/(?P[0-9]+)$', + views.edit_model_switch, + name='edit-model-switch'), + url(r'^del_model_switch/(?P[0-9]+)$', + views.del_model_switch, + name='del-model-switch'), + url(r'^new_constructor_switch/$', + views.new_constructor_switch, + name='new-constructor-switch' + ), + url(r'^edit_constructor_switch/(?P[0-9]+)$', + views.edit_constructor_switch, + name='edit-constructor-switch'), + url(r'^del_constructor_switch/(?P[0-9]+)$', + views.del_constructor_switch, + name='del-constructor-switch'), ] diff --git a/topologie/views.py b/topologie/views.py index 1c5b4985..e824066c 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -42,16 +42,37 @@ from django.contrib.auth.decorators import login_required, permission_required from django.db import IntegrityError from django.db import transaction from django.db.models import ProtectedError +from django.core.exceptions import ValidationError from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from reversion import revisions as reversion from reversion.models import Version -from topologie.models import Switch, Port, Room, Stack +from topologie.models import ( + Switch, + Port, + Room, + Stack, + ModelSwitch, + ConstructorSwitch +) from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm -from topologie.forms import AddPortForm, EditRoomForm, StackForm +from topologie.forms import ( + AddPortForm, + EditRoomForm, + StackForm, + EditModelSwitchForm, + EditConstructorSwitchForm, + CreatePortsForm +) from users.views import form from re2o.utils import SortTable -from machines.forms import DomainForm, NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm +from machines.forms import ( + DomainForm, + NewMachineForm, + EditMachineForm, + EditInterfaceForm, + AddInterfaceForm +) from machines.views import generate_ipv4_mbf_param from preferences.models import AssoOption, GeneralOption @@ -71,6 +92,18 @@ def index(request): request.GET.get('order'), SortTable.TOPOLOGIE_INDEX ) + 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) return render(request, 'topologie/index.html', { 'switch_list': switch_list }) @@ -104,6 +137,18 @@ def history(request, object_name, object_id): except Room.DoesNotExist: messages.error(request, "Stack inexistante") return redirect(reverse('topologie:index')) + elif object_name == 'model_switch': + try: + object_instance = ModelSwitch.objects.get(pk=object_id) + except ModelSwitch.DoesNotExist: + messages.error(request, "SwitchModel inexistant") + return redirect(reverse('topologie:index')) + elif object_name == 'constructor_switch': + try: + object_instance = ConstructorSwitch.objects.get(pk=object_id) + except ConstructorSwitch.DoesNotExist: + messages.error(request, "SwitchConstructor inexistant") + return redirect(reverse('topologie:index')) else: messages.error(request, "Objet inconnu") return redirect(reverse('topologie:index')) @@ -139,7 +184,9 @@ def index_port(request, switch_id): .select_related('room')\ .select_related('machine_interface__domain__extension')\ .select_related('machine_interface__machine__user')\ - .select_related('related__switch__switch_interface__domain__extension')\ + .select_related( + 'related__switch__switch_interface__domain__extension' + )\ .select_related('switch') port_list = SortTable.sort( port_list, @@ -199,6 +246,30 @@ def index_stack(request): }) +@login_required +@permission_required('cableur') +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, + }) + + @login_required @permission_required('infra') def new_port(request, switch_id): @@ -274,7 +345,7 @@ def del_port(request, port_id): port.delete() reversion.set_user(request.user) reversion.set_comment("Destruction") - messages.success(request, "Le port a eté détruit") + messages.success(request, "Le port a été détruit") except ProtectedError: messages.error(request, "Le port %s est affecté à un autre objet,\ impossible de le supprimer" % port) @@ -410,7 +481,7 @@ def new_switch(request): reversion.set_comment("Création") messages.success(request, "Le switch a été créé") return redirect(reverse('topologie:index')) - i_mbf_param = generate_ipv4_mbf_param( interface, False ) + i_mbf_param = generate_ipv4_mbf_param( interface, False) return form({ 'topoform': switch, 'machineform': machine, @@ -420,6 +491,42 @@ def new_switch(request): }, 'topologie/switch.html', request) +@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 + nb_ports = switch.ports.count() + if nb_ports > 0: + ports = switch.ports.order_by('port').values('port') + s_begin = ports.first().get('port') + s_end = ports.last().get('port') + + port_form = CreatePortsForm( + request.POST or None, + initial={'begin': s_begin, 'end': s_end} + ) + + if port_form.is_valid(): + begin = port_form.cleaned_data['begin'] + end = port_form.cleaned_data['end'] + try: + switch.create_ports(begin, end) + messages.success(request, "Ports créés.") + except ValidationError as e: + messages.error(request, ''.join(e)) + + return redirect("/topologie/switch/" + str(switch.id)) + + return form({'topoform': port_form}, 'topologie/switch.html', request) + + @login_required @permission_required('infra') def edit_switch(request, switch_id): @@ -548,3 +655,129 @@ def del_room(request, room_id): 'objet': room, 'objet_name': 'Chambre' }, 'topologie/delete.html', request) + + +@login_required +@permission_required('infra') +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 +@permission_required('infra') +def edit_model_switch(request, model_switch_id): + """ Edition d'un modèle de switch""" + try: + model_switch = ModelSwitch.objects.get(pk=model_switch_id) + except ModelSwitch.DoesNotExist: + messages.error(request, u"Modèle inconnu") + return redirect("/topologie/index_model_switch/") + 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 +@permission_required('infra') +def del_model_switch(request, model_switch_id): + """ Suppression d'un modèle de switch""" + try: + model_switch = ModelSwitch.objects.get(pk=model_switch_id) + except ModelSwitch.DoesNotExist: + messages.error(request, u"Modèle inexistant") + return redirect("/topologie/index_model_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 +@permission_required('infra') +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 +@permission_required('infra') +def edit_constructor_switch(request, constructor_switch_id): + """ Edition d'un constructeur de switch""" + try: + constructor_switch = ConstructorSwitch.objects.get(pk=constructor_switch_id) + except ConstructorSwitch.DoesNotExist: + messages.error(request, u"Constructeur inconnu") + return redirect("/topologie/index_model_switch/") + 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 +@permission_required('infra') +def del_constructor_switch(request, constructor_switch_id): + """ Suppression d'un constructeur de switch""" + try: + constructor_switch = ConstructorSwitch.objects.get(pk=constructor_switch_id) + except ConstructorSwitch.DoesNotExist: + messages.error(request, u"Constructeur inexistant") + return redirect("/topologie/index_model_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)
{% include "buttons/sort.html" with prefix='switch' col='loc' text='Localisation' %} {% include "buttons/sort.html" with prefix='switch' col='ports' text='Ports' %} {% include "buttons/sort.html" with prefix='switch' col='stack' text='Stack' %}Id interne stackId stackModèle Détails
{{switch.number}} {{switch.stack.name}} {{switch.stack_member_id}}{{switch.model}} {{switch.details}} {% include 'buttons/history.html' with href='topologie:history' name='switch' id=switch.pk%} {% if is_infra %} {% include 'buttons/edit.html' with href='topologie:edit-switch' id=switch.pk %} {% include 'buttons/suppr.html' with href='machines:del-interface' id=switch.switch_interface.id %} + {% include 'buttons/add.html' with href='topologie:create-ports' id=switch.pk desc='Création de ports'%} {% endif %}