diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py index fccbea1d..11399633 100644 --- a/re2o/templatetags/acl.py +++ b/re2o/templatetags/acl.py @@ -129,6 +129,7 @@ MODEL_NAME = { 'Room': topologie.models.Room, 'Building': topologie.models.Building, 'SwitchBay': topologie.models.SwitchBay, + 'PortProfile': topologie.models.PortProfile, # users 'User': users.models.User, 'Adherent': users.models.Adherent, diff --git a/re2o/views.py b/re2o/views.py index 3c5cde09..d803505e 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -111,6 +111,7 @@ HISTORY_BIND = { 'accesspoint': topologie.models.AccessPoint, 'switchbay': topologie.models.SwitchBay, 'building': topologie.models.Building, + 'portprofile': topologie.models.PortProfile, }, 'machines': { 'machine': machines.models.Machine, diff --git a/topologie/admin.py b/topologie/admin.py index 62ffd6c4..d2a25461 100644 --- a/topologie/admin.py +++ b/topologie/admin.py @@ -38,7 +38,8 @@ from .models import ( ConstructorSwitch, AccessPoint, SwitchBay, - Building + Building, + PortProfile, ) @@ -86,6 +87,9 @@ class BuildingAdmin(VersionAdmin): """Administration d'un batiment""" pass +class PortProfileAdmin(VersionAdmin): + """Administration of a port profile""" + pass admin.site.register(Port, PortAdmin) admin.site.register(AccessPoint, AccessPointAdmin) @@ -96,3 +100,4 @@ admin.site.register(ModelSwitch, ModelSwitchAdmin) admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin) admin.site.register(Building, BuildingAdmin) admin.site.register(SwitchBay, SwitchBayAdmin) +admin.site.register(PortProfile, PortProfileAdmin) diff --git a/topologie/forms.py b/topologie/forms.py index 18831217..377a39b3 100644 --- a/topologie/forms.py +++ b/topologie/forms.py @@ -35,6 +35,7 @@ from __future__ import unicode_literals from django import forms from django.forms import ModelForm from django.db.models import Prefetch +from django.utils.translation import ugettext_lazy as _ from machines.models import Interface from machines.forms import ( @@ -53,6 +54,7 @@ from .models import ( AccessPoint, SwitchBay, Building, + PortProfile, ) @@ -262,3 +264,59 @@ class EditBuildingForm(FormRevMixin, ModelForm): def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) 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 + + diff --git a/topologie/migrations/0061_portprofile.py b/topologie/migrations/0061_portprofile.py new file mode 100644 index 00000000..7b6af2ed --- /dev/null +++ b/topologie/migrations/0061_portprofile.py @@ -0,0 +1,36 @@ +# -*- 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), + ), + ] diff --git a/topologie/migrations/0062_auto_20180609_1151.py b/topologie/migrations/0062_auto_20180609_1151.py new file mode 100644 index 00000000..3f074f7c --- /dev/null +++ b/topologie/migrations/0062_auto_20180609_1151.py @@ -0,0 +1,66 @@ +# -*- 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'), + ), + ] diff --git a/topologie/migrations/0063_auto_20180609_1158.py b/topologie/migrations/0063_auto_20180609_1158.py new file mode 100644 index 00000000..59ea8732 --- /dev/null +++ b/topologie/migrations/0063_auto_20180609_1158.py @@ -0,0 +1,20 @@ +# -*- 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'), + ), + ] diff --git a/topologie/migrations/0064_auto_20180609_1220.py b/topologie/migrations/0064_auto_20180609_1220.py new file mode 100644 index 00000000..f657a612 --- /dev/null +++ b/topologie/migrations/0064_auto_20180609_1220.py @@ -0,0 +1,20 @@ +# -*- 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'), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index e1c945c7..cdf30787 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -46,6 +46,7 @@ from django.dispatch import receiver from django.core.exceptions import ValidationError from django.db import IntegrityError from django.db import transaction +from django.utils.translation import ugettext_lazy as _ from reversion import revisions as reversion from machines.models import Machine, regen @@ -488,6 +489,60 @@ class Room(AclMixin, RevMixin, models.Model): 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) def ap_post_save(**_kwargs): """Regeneration des noms des bornes vers le controleur""" diff --git a/topologie/templates/topologie/aff_port_profile.html b/topologie/templates/topologie/aff_port_profile.html new file mode 100644 index 00000000..b4b936c5 --- /dev/null +++ b/topologie/templates/topologie/aff_port_profile.html @@ -0,0 +1,46 @@ +{% load acl %} +{% load i18n %} + +
{% trans "Name" %} | +{% trans "VLAN untagged" %} | +{% trans "VLAN(s) tagged" %} | +{% trans "RADIUS type" %} | +{% trans "RADIUS mode" %} | +|
---|---|---|---|---|---|
{{port_profile.name}} | +{{port_profile.vlan_untagged}} | ++ {{port_profile.vlan_tagged.all|join:", "}} + | +{{port_profile.radius_type}} | +{{port_profile.radius_mode}} | ++ {% 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 %} + | +