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..3ad2e7be 100644
--- a/topologie/forms.py
+++ b/topologie/forms.py
@@ -34,7 +34,7 @@ from __future__ import unicode_literals
from machines.models import Interface
from django.forms import ModelForm
-from .models import Port, Switch, Room, Stack
+from .models import Port, Switch, Room, Stack, ModelSwitch, ConstructorSwitch
class PortForm(ModelForm):
@@ -136,3 +136,25 @@ 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 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..0f277434 100644
--- a/topologie/models.py
+++ b/topologie/models.py
@@ -93,12 +93,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')
@@ -121,6 +127,26 @@ class Switch(models.Model):
ne peut être nul"})
+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):
""" Definition d'un port. Relié à un switch(foreign_key),
un port peut etre relié de manière exclusive à :
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 %}
+
+
+
+
+ {% include "buttons/sort.html" with prefix='constructor-switch' col='name' text='Constructeur' %} |
+ |
+
+
+ {% for constructor_switch in constructor_switch_list %}
+
+ {{constructor_switch}} |
+
+
+
+
+ {% if is_infra %}
+
+
+
+
+
+
+ {% endif %}
+ |
+
+ {% endfor %}
+
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 %}
+
+
+
+
+ {% 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' %} |
+ |
+
+
+ {% for model_switch in model_switch_list %}
+
+ {{model_switch.reference}} |
+ {{model_switch.constructor}} |
+
+
+
+
+ {% if is_infra %}
+
+
+
+
+
+
+ {% endif %}
+ |
+
+ {% endfor %}
+
diff --git a/topologie/templates/topologie/aff_switch.html b/topologie/templates/topologie/aff_switch.html
index c0d6c55f..eb326421 100644
--- a/topologie/templates/topologie/aff_switch.html
+++ b/topologie/templates/topologie/aff_switch.html
@@ -30,7 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% 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 stack |
+ Id stack |
+ Modèle |
Détails |
|
@@ -47,6 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{{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%}
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/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/urls.py b/topologie/urls.py
index 77a78b97..4175c68c 100644
--- a/topologie/urls.py
+++ b/topologie/urls.py
@@ -54,6 +54,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 +74,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 dec681b6..5cd413f7 100644
--- a/topologie/views.py
+++ b/topologie/views.py
@@ -45,12 +45,31 @@ 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
+)
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
@@ -103,6 +122,18 @@ def history(request, object_name, object_id):
except Room.DoesNotExist:
messages.error(request, "Stack inexistante")
return redirect("/topologie/")
+ elif object_name == 'model_switch':
+ try:
+ object_instance = ModelSwitch.objects.get(pk=object_id)
+ except ModelSwitch.DoesNotExist:
+ messages.error(request, "SwitchModel inexistant")
+ return redirect("/topologie/")
+ elif object_name == 'constructor_switch':
+ try:
+ object_instance = ConstructorSwitch.objects.get(pk=object_id)
+ except ConstructorSwitch.DoesNotExist:
+ messages.error(request, "SwitchConstructor inexistant")
+ return redirect("/topologie/")
else:
messages.error(request, "Objet inconnu")
return redirect("/topologie/")
@@ -198,6 +229,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):
@@ -538,3 +593,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)
|