Ce serveur Gitlab sera éteint le 30 juin 2020, pensez à migrer vos projets vers les serveurs gitlab-research.centralesupelec.fr et gitlab-student.centralesupelec.fr !

Commit 7ab0d656 authored by Fernet Laouen's avatar Fernet Laouen Committed by root

add model PortProfile

parent d610ac6d
...@@ -129,6 +129,7 @@ MODEL_NAME = { ...@@ -129,6 +129,7 @@ MODEL_NAME = {
'Room': topologie.models.Room, 'Room': topologie.models.Room,
'Building': topologie.models.Building, 'Building': topologie.models.Building,
'SwitchBay': topologie.models.SwitchBay, 'SwitchBay': topologie.models.SwitchBay,
'PortProfile': topologie.models.PortProfile,
# users # users
'User': users.models.User, 'User': users.models.User,
'Adherent': users.models.Adherent, 'Adherent': users.models.Adherent,
......
...@@ -111,6 +111,7 @@ HISTORY_BIND = { ...@@ -111,6 +111,7 @@ HISTORY_BIND = {
'accesspoint': topologie.models.AccessPoint, 'accesspoint': topologie.models.AccessPoint,
'switchbay': topologie.models.SwitchBay, 'switchbay': topologie.models.SwitchBay,
'building': topologie.models.Building, 'building': topologie.models.Building,
'portprofile': topologie.models.PortProfile,
}, },
'machines': { 'machines': {
'machine': machines.models.Machine, 'machine': machines.models.Machine,
......
...@@ -38,7 +38,8 @@ from .models import ( ...@@ -38,7 +38,8 @@ from .models import (
ConstructorSwitch, ConstructorSwitch,
AccessPoint, AccessPoint,
SwitchBay, SwitchBay,
Building Building,
PortProfile,
) )
...@@ -86,6 +87,9 @@ class BuildingAdmin(VersionAdmin): ...@@ -86,6 +87,9 @@ class BuildingAdmin(VersionAdmin):
"""Administration d'un batiment""" """Administration d'un batiment"""
pass pass
class PortProfileAdmin(VersionAdmin):
"""Administration of a port profile"""
pass
admin.site.register(Port, PortAdmin) admin.site.register(Port, PortAdmin)
admin.site.register(AccessPoint, AccessPointAdmin) admin.site.register(AccessPoint, AccessPointAdmin)
...@@ -96,3 +100,4 @@ admin.site.register(ModelSwitch, ModelSwitchAdmin) ...@@ -96,3 +100,4 @@ admin.site.register(ModelSwitch, ModelSwitchAdmin)
admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin) admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin)
admin.site.register(Building, BuildingAdmin) admin.site.register(Building, BuildingAdmin)
admin.site.register(SwitchBay, SwitchBayAdmin) admin.site.register(SwitchBay, SwitchBayAdmin)
admin.site.register(PortProfile, PortProfileAdmin)
...@@ -35,6 +35,7 @@ from __future__ import unicode_literals ...@@ -35,6 +35,7 @@ from __future__ import unicode_literals
from django import forms from django import forms
from django.forms import ModelForm from django.forms import ModelForm
from django.db.models import Prefetch from django.db.models import Prefetch
from django.utils.translation import ugettext_lazy as _
from machines.models import Interface from machines.models import Interface
from machines.forms import ( from machines.forms import (
...@@ -53,6 +54,7 @@ from .models import ( ...@@ -53,6 +54,7 @@ from .models import (
AccessPoint, AccessPoint,
SwitchBay, SwitchBay,
Building, Building,
PortProfile,
) )
...@@ -262,3 +264,59 @@ class EditBuildingForm(FormRevMixin, ModelForm): ...@@ -262,3 +264,59 @@ class EditBuildingForm(FormRevMixin, ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EditBuildingForm, self).__init__(*args, prefix=prefix, **kwargs) super(EditBuildingForm, self).__init__(*args, prefix=prefix, **kwargs)
class NewPortProfileForm(FormRevMixin, ModelForm):
"""Form to create a port profile"""
class Meta:
model = PortProfile
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(NewPortProfileForm, self).__init__(*args,
prefix=prefix,
**kwargs)
def clean(self):
cleaned_data = super(NewPortProfileForm, self).clean()
radius_type = cleaned_data.get('radius_type')
radius_mode = cleaned_data.get('radius_mode')
if radius_type == 'NO' and radius_mode:
raise forms.ValidationError(_("You can't specify a RADIUS mode"
" with RADIUS type NO"))
elif radius_type != 'NO' and not radius_mode:
raise forms.ValidationError(_("You have to specify a RADIUS"
" mode"))
return cleaned_data
class EditPortProfileForm(FormRevMixin, ModelForm):
"""Form to edit a port profile"""
class Meta:
model = PortProfile
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EditPortProfileForm, self).__init__(*args,
prefix=prefix,
**kwargs)
def clean(self):
cleaned_data = super(EditPortProfileForm, self).clean()
radius_type = cleaned_data.get('radius_type')
radius_mode = cleaned_data.get('radius_mode')
if radius_type == 'NO' and radius_mode:
raise forms.ValidationError(_("You can't specify a RADIUS mode"
" with RADIUS type NO"))
elif radius_type != 'NO' and not radius_mode:
raise forms.ValidationError(_("You have to specify a RADIUS"
" mode"))
return cleaned_data
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-05-26 22:26
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import re2o.mixins
class Migration(migrations.Migration):
dependencies = [
('machines', '0081_auto_20180521_1413'),
('topologie', '0060_server'),
]
operations = [
migrations.CreateModel(
name='PortProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('room_default', models.BooleanField()),
('hotspot_default', models.BooleanField()),
('uplink_default', models.BooleanField()),
('orga_machine_default', models.BooleanField()),
('radius_type', models.CharField(choices=[('NO', 'NO'), ('802.1X', '802.1X'), ('MAC-radius', 'MAC-radius')], max_length=32)),
('radius_mode', models.CharField(choices=[('STRICT', 'STRICT'), ('COMMON', 'COMMON')], max_length=32)),
('vlan_tagged', models.ManyToManyField(related_name='vlan_tagged', to='machines.Vlan')),
('vlan_untagged', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlan_untagged', to='machines.Vlan')),
],
options={
'permissions': (('view_port_profile', 'Can view a port profile object'),),
},
bases=(re2o.mixins.AclMixin, models.Model),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-09 16:51
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0061_portprofile'),
]
operations = [
migrations.AlterModelOptions(
name='portprofile',
options={'permissions': (('view_port_profile', 'Can view a port profile object'),), 'verbose_name': 'Port profile', 'verbose_name_plural': 'Port profiles'},
),
migrations.AddField(
model_name='portprofile',
name='name',
field=models.CharField(default='Sans nom', max_length=255, verbose_name='Name'),
preserve_default=False,
),
migrations.AlterField(
model_name='portprofile',
name='hotspot_default',
field=models.BooleanField(verbose_name='Hotspot default'),
),
migrations.AlterField(
model_name='portprofile',
name='orga_machine_default',
field=models.BooleanField(verbose_name='Organisation machine default'),
),
migrations.AlterField(
model_name='portprofile',
name='radius_mode',
field=models.CharField(choices=[('STRICT', 'STRICT'), ('COMMON', 'COMMON')], max_length=32, verbose_name='RADIUS mode'),
),
migrations.AlterField(
model_name='portprofile',
name='radius_type',
field=models.CharField(choices=[('NO', 'NO'), ('802.1X', '802.1X'), ('MAC-radius', 'MAC-radius')], max_length=32, verbose_name='RADIUS type'),
),
migrations.AlterField(
model_name='portprofile',
name='room_default',
field=models.BooleanField(verbose_name='Room default'),
),
migrations.AlterField(
model_name='portprofile',
name='uplink_default',
field=models.BooleanField(verbose_name='Uplink default'),
),
migrations.AlterField(
model_name='portprofile',
name='vlan_tagged',
field=models.ManyToManyField(related_name='vlan_tagged', to='machines.Vlan', verbose_name='VLAN(s) tagged'),
),
migrations.AlterField(
model_name='portprofile',
name='vlan_untagged',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlan_untagged', to='machines.Vlan', verbose_name='VLAN untagged'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-09 16:58
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('topologie', '0062_auto_20180609_1151'),
]
operations = [
migrations.AlterField(
model_name='portprofile',
name='vlan_tagged',
field=models.ManyToManyField(blank=True, related_name='vlan_tagged', to='machines.Vlan', verbose_name='VLAN(s) tagged'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-09 17:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('topologie', '0063_auto_20180609_1158'),
]
operations = [
migrations.AlterField(
model_name='portprofile',
name='radius_mode',
field=models.CharField(blank=True, choices=[('STRICT', 'STRICT'), ('COMMON', 'COMMON')], max_length=32, null=True, verbose_name='RADIUS mode'),
),
]
...@@ -46,6 +46,7 @@ from django.dispatch import receiver ...@@ -46,6 +46,7 @@ from django.dispatch import receiver
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import IntegrityError from django.db import IntegrityError
from django.db import transaction from django.db import transaction
from django.utils.translation import ugettext_lazy as _
from reversion import revisions as reversion from reversion import revisions as reversion
from machines.models import Machine, regen from machines.models import Machine, regen
...@@ -488,6 +489,60 @@ class Room(AclMixin, RevMixin, models.Model): ...@@ -488,6 +489,60 @@ class Room(AclMixin, RevMixin, models.Model):
return self.name return self.name
class PortProfile(AclMixin, models.Model):
"""Contains the information of the ports' configuration for a switch"""
TYPES = (
('NO', 'NO'),
('802.1X', '802.1X'),
('MAC-radius', 'MAC-radius'),
)
MODES = (
('STRICT', 'STRICT'),
('COMMON', 'COMMON'),
)
name = models.CharField(max_length=255, verbose_name=_("Name"))
room_default = models.BooleanField(verbose_name=_("Room default"))
hotspot_default = models.BooleanField(_("Hotspot default"))
uplink_default = models.BooleanField(_("Uplink default"))
orga_machine_default = models.BooleanField(_("Organisation machine"
" default"))
vlan_untagged = models.ForeignKey(
'machines.Vlan',
related_name='vlan_untagged',
on_delete=models.SET_NULL,
blank=True,
null=True,
verbose_name=_("VLAN untagged")
)
vlan_tagged = models.ManyToManyField(
'machines.Vlan',
related_name='vlan_tagged',
blank=True,
verbose_name=_("VLAN(s) tagged"))
radius_type = models.CharField(
max_length=32,
choices=TYPES,
verbose_name=_("RADIUS type")
)
radius_mode = models.CharField(
max_length=32,
choices=MODES,
blank=True,
null=True,
verbose_name=_("RADIUS mode")
)
class Meta:
permissions = (
("view_port_profile", _("Can view a port profile object")),
)
verbose_name = _("Port profile")
verbose_name_plural = _("Port profiles")
def __str__(self):
return self.name
@receiver(post_save, sender=AccessPoint) @receiver(post_save, sender=AccessPoint)
def ap_post_save(**_kwargs): def ap_post_save(**_kwargs):
"""Regeneration des noms des bornes vers le controleur""" """Regeneration des noms des bornes vers le controleur"""
......
{% load acl %}
{% load i18n %}
<div class="table-responsive">
{% if port_profile_list.paginator %}
{% include "pagination.html" with list=port_profile_list %}
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "Name" %}</th>
<th>{% trans "VLAN untagged" %}</th>
<th>{% trans "VLAN(s) tagged" %}</th>
<th>{% trans "RADIUS type" %}</th>
<th>{% trans "RADIUS mode" %}</th>
</tr>
</thead>
{% for port_profile in port_profile_list %}
<tr>
<td>{{port_profile.name}}</td>
<td>{{port_profile.vlan_untagged}}</td>
<td>
{{port_profile.vlan_tagged.all|join:", "}}
</td>
<td>{{port_profile.radius_type}}</td>
<td>{{port_profile.radius_mode}}</td>
<td class="text-right">
{% include 'buttons/history.html' with href='topologie:history' name='portprofile' id=port_profile.pk %}
{% can_edit port_profile %}
{% include 'buttons/edit.html' with href='topologie:edit-port-profile' id=port_profile.pk %}
{% acl_end %}
{% can_delete port_profile %}
{% include 'buttons/suppr.html' with href='topologie:del-port-profile' id=port_profile.pk %}
{% acl_end %}
</td>
</tr>
{% endfor %}
</table>
{% if port_profile_list.paginator %}
{% include "pagination.html" with list=port_profile_list %}
{% endif %}
</div>
...@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load bootstrap3 %} {% load bootstrap3 %}
{% load acl %} {% load acl %}
{% load i18n %}
{% block title %}Switchs{% endblock %} {% block title %}Switchs{% endblock %}
...@@ -72,5 +73,14 @@ Topologie des Switchs ...@@ -72,5 +73,14 @@ Topologie des Switchs
<br /> <br />
<br /> <br />
<h2>{% trans "Port profiles" %}</h2>
{% can_create PortProfile %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-port-profile' %}"><i class="fa fa-plus"></i>{% trans " Add a port profile" %}</a>
<hr>
{% acl_end %}
{% include "topologie/aff_port_profile.html" with port_profile_list=port_profile_list %}
<br />
<br />
<br />
{% endblock %} {% endblock %}
...@@ -113,4 +113,13 @@ urlpatterns = [ ...@@ -113,4 +113,13 @@ urlpatterns = [
url(r'^del_building/(?P<buildingid>[0-9]+)$', url(r'^del_building/(?P<buildingid>[0-9]+)$',
views.del_building, views.del_building,
name='del-building'), name='del-building'),
url(r'^new_port_profile/$',
views.new_port_profile,
name='new-port-profile'),
url(r'^edit_port_profile/(?P<portprofileid>[0-9]+)$',
views.edit_port_profile,
name='edit-port-profile'),
url(r'^del_port_profile/(?P<portprofileid>[0-9]+)$',
views.del_port_profile,
name='del-port-profile'),
] ]
...@@ -47,6 +47,7 @@ from django.template.loader import get_template ...@@ -47,6 +47,7 @@ from django.template.loader import get_template
from django.template import Context, Template, loader from django.template import Context, Template, loader
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.translation import ugettext as _
import tempfile import tempfile
...@@ -80,6 +81,7 @@ from .models import ( ...@@ -80,6 +81,7 @@ from .models import (
SwitchBay, SwitchBay,
Building, Building,
Server, Server,
PortProfile,
) )
from .forms import ( from .forms import (
EditPortForm, EditPortForm,
...@@ -94,7 +96,9 @@ from .forms import ( ...@@ -94,7 +96,9 @@ from .forms import (
AddAccessPointForm, AddAccessPointForm,
EditAccessPointForm, EditAccessPointForm,
EditSwitchBayForm, EditSwitchBayForm,
EditBuildingForm EditBuildingForm,
NewPortProfileForm,
EditPortProfileForm,
) )
from subprocess import ( from subprocess import (
...@@ -124,8 +128,12 @@ def index(request): ...@@ -124,8 +128,12 @@ def index(request):
request.GET.get('order'), request.GET.get('order'),
SortTable.TOPOLOGIE_INDEX SortTable.TOPOLOGIE_INDEX
) )
port_profile_list = PortProfile.objects.all()
pagination_number = GeneralOption.get_cached_value('pagination_number') pagination_number = GeneralOption.get_cached_value('pagination_number')
switch_list = re2o_paginator(request, switch_list, pagination_number) switch_list = re2o_paginator(request, switch_list, pagination_number)
port_profile_list = re2o_paginator(request, port_profile_list, pagination_number)
if any(service_link.need_regen() for service_link in Service_link.objects.filter(service__service_type='graph_topo')): if any(service_link.need_regen() for service_link in Service_link.objects.filter(service__service_type='graph_topo')):
make_machine_graph() make_machine_graph()
...@@ -137,7 +145,7 @@ def index(request): ...@@ -137,7 +145,7 @@ def index(request):
return render( return render(
request, request,
'topologie/index.html', 'topologie/index.html',
{'switch_list': switch_list} {'switch_list': switch_list, 'port_profile_list': port_profile_list}
) )
...@@ -955,6 +963,59 @@ def del_constructor_switch(request, constructor_switch, **_kwargs): ...@@ -955,6 +963,59 @@ def del_constructor_switch(request, constructor_switch, **_kwargs):
}, 'topologie/delete.html', request) }, 'topologie/delete.html', request)
@login_required
@can_create(PortProfile)
def new_port_profile(request):
"""Create a new port profile"""
port_profile = NewPortProfileForm(request.POST or None)
if port_profile.is_valid():
port_profile.save()
messages.success(request, _("Port profile created"))
return redirect(reverse('topologie:index'))
return form(
{'topoform': port_profile, 'action_name': _("Create")},
'topologie/topo.html',
request
)
@login_required
@can_edit(PortProfile)
def edit_port_profile(request, port_profile, **_kwargs):
"""Edit a port profile"""
port_profile = EditPortProfileForm(request.POST or None, instance=port_profile)
if port_profile.is_valid():
if port_profile.changed_data:
port_profile.save()
messages.success(request, _("Port profile modified"))
return redirect(reverse('topologie:index'))
return form(
{'topoform': port_profile, 'action_name': _("Edit")},
'topologie/topo.html',
request
)
@login_required
@can_delete(PortProfile)
def del_port_profile(request, port_profile, **_kwargs):
"""Delete a port profile"""
if request.method == 'POST':
try:
port_profile.delete()
messages.success(request, _("The port profile was successfully"
" deleted"))
except ProtectedError:
messages.success(request, _("Impossible to delete the port"
" profile"))
return redirect(reverse('topologie:index'))
return form(
{'objet': port_profile, 'objet_name': _("Port profile")},
'topologie/delete.html',
request
)
def make_machine_graph(): def make_machine_graph():
""" """
Create the graph of switchs, machines and access points. Create the graph of switchs, machines and access points.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment