From 3ec4fdd9d9de31dae87e31a8afc84abe972bc882 Mon Sep 17 00:00:00 2001 From: chirac Date: Sun, 21 Jul 2019 01:02:32 +0200 Subject: [PATCH 1/4] Profile default different for dormitories (option) --- .../migrations/0072_auto_20190720_2318.py | 34 +++++++++++++++++++ topologie/models.py | 20 +++++++++-- .../templates/topologie/aff_port_profile.html | 4 +-- 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 topologie/migrations/0072_auto_20190720_2318.py diff --git a/topologie/migrations/0072_auto_20190720_2318.py b/topologie/migrations/0072_auto_20190720_2318.py new file mode 100644 index 00000000..3c403bfa --- /dev/null +++ b/topologie/migrations/0072_auto_20190720_2318.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-07-20 21:18 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('topologie', '0071_auto_20190218_1936'), + ] + + operations = [ + migrations.AlterModelOptions( + name='room', + options={'ordering': ['building__name'], 'permissions': (('view_room', 'Can view a room object'),), 'verbose_name': 'room', 'verbose_name_plural': 'rooms'}, + ), + migrations.AddField( + model_name='portprofile', + name='on_dormitory', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dormitory_ofprofil', to='topologie.Dormitory', verbose_name='Profil on dormitory'), + ), + migrations.AlterField( + model_name='portprofile', + name='profil_default', + field=models.CharField(blank=True, choices=[('room', 'Room'), ('access_point', 'Access point'), ('uplink', 'Uplink'), ('asso_machine', 'Organisation machine'), ('nothing', 'Nothing')], max_length=32, null=True, verbose_name='Default profile'), + ), + migrations.AlterUniqueTogether( + name='portprofile', + unique_together=set([('on_dormitory', 'profil_default')]), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index dee8abb3..a379e005 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -650,7 +650,7 @@ class Port(AclMixin, RevMixin, models.Model): :returns: the profile of self (port)""" def profile_or_nothing(profile): port_profile = PortProfile.objects.filter( - profil_default=profile).first() + profil_default=profile).filter(switch__switchbay__building__dormitory).first() if port_profile: return port_profile else: @@ -791,9 +791,16 @@ class PortProfile(AclMixin, RevMixin, models.Model): choices=PROFIL_DEFAULT, blank=True, null=True, - unique=True, verbose_name=_("Default profile") ) + on_dormitory = models.ForeignKey( + 'topologie.Dormitory', + related_name='dormitory_ofprofil', + on_delete=models.SET_NULL, + blank=True, + null=True, + verbose_name=_("Profil on dormitory") + ) vlan_untagged = models.ForeignKey( 'machines.Vlan', related_name='vlan_untagged', @@ -871,6 +878,7 @@ class PortProfile(AclMixin, RevMixin, models.Model): ) verbose_name = _("port profile") verbose_name_plural = _("port profiles") + unique_together = ['on_dormitory', 'profil_default'] security_parameters_fields = [ 'loop_protect', @@ -893,6 +901,14 @@ class PortProfile(AclMixin, RevMixin, models.Model): def security_parameters_as_str(self): return ','.join(self.security_parameters_enabled) + def clean(self): + """ Check that there is only one generic profil default""" + super(PortProfile, self).clean() + if self.profil_default and not self.on_dormitory and PortProfile.objects.exclude(id=self.id).filter(profil_default=self.profil_default).exclude(on_dormitory__isnull=False).exists(): + raise ValidationError( + {'profil_default': _("A default profile for all dormitory of that type already exists.")} + ) + def __str__(self): return self.name diff --git a/topologie/templates/topologie/aff_port_profile.html b/topologie/templates/topologie/aff_port_profile.html index b335904e..4ed8a7b4 100644 --- a/topologie/templates/topologie/aff_port_profile.html +++ b/topologie/templates/topologie/aff_port_profile.html @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Name" %} - {% trans "Default for" %} + {% trans "Default for and place" %} {% trans "VLANs" %} {% trans "RADIUS settings" %} {% trans "Speed limit" %} @@ -47,7 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% for port_profile in port_profile_list %} {{ port_profile.name }} - {{ port_profile.profil_default }} + {{ port_profile.profil_default }} {% if port_profile.profil_default%} - {% if port_profile.on_dormitory %} on {{ port_profile.on_dormitory }} {% else %} Everywhere {% endif %}{% endif %} {% if port_profile.vlan_untagged %} {% trans "Untagged: " %}{{ port_profile.vlan_untagged }} From 5b112657c9c87795802a99134e7350fc926ae02f Mon Sep 17 00:00:00 2001 From: chirac Date: Sun, 21 Jul 2019 01:25:04 +0200 Subject: [PATCH 2/4] Returns correct port profile --- topologie/models.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/topologie/models.py b/topologie/models.py index a379e005..c01d5b53 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -379,6 +379,14 @@ class Switch(AclMixin, Machine): modules.append((module_of_self.slot, module_of_self.module.reference)) return modules + @cached_property + def get_dormitory(self): + """Returns the dormitory of that switch""" + if self.switchbay: + return self.switchbay.building.dormitory + else: + return None + def __str__(self): return str(self.get_name) @@ -647,10 +655,18 @@ class Port(AclMixin, RevMixin, models.Model): @cached_property def get_port_profile(self): """Return the config profil for this port - :returns: the profile of self (port)""" + :returns: the profile of self (port) + + If is defined a custom profile, returns it + elIf a default profile is defined for its dormitory, returns it + Else, returns the global default profil + If not exists, create a nothing profile""" def profile_or_nothing(profile): - port_profile = PortProfile.objects.filter( - profil_default=profile).filter(switch__switchbay__building__dormitory).first() + if self.switch.get_dormitory: + port_profile = PortProfile.objects.filter( + profil_default=profile).filter(on_dormitory=self.switch.get_dormitory).first() + if not port_profile: + port_profile = PortProfile.objects.filter(profil_default=profile).first() if port_profile: return port_profile else: From 7cc0fd1e66353e14a4326d72568a1e61c32046e4 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 27 Jul 2019 01:53:06 +0200 Subject: [PATCH 3/4] =?UTF-8?q?Mise=20en=20cache=20et=20gestion=20correcte?= =?UTF-8?q?=20des=20profile=20de=20port=20par=20r=C3=A9sidence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- topologie/models.py | 69 ++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/topologie/models.py b/topologie/models.py index c01d5b53..2eaa3364 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -387,6 +387,50 @@ class Switch(AclMixin, Machine): else: return None + @classmethod + def nothing_profile(cls): + """Return default nothing port profile""" + nothing_profile, _created = PortProfile.objects.get_or_create( + profil_default='nothing', + name='nothing', + radius_type='NO' + ) + return nothing_profile + + def profile_type_or_nothing(self, profile_type): + """Return the profile for a profile_type of this switch + + If exists, returns the defined default profile for a profile type on the dormitory which + the switch belongs + + Otherwise, returns the nothing profile""" + profile_queryset = PortProfile.objects.filter(profil_default=profile_type) + if self.get_dormitory: + port_profile = profile_queryset.filter(on_dormitory=self.get_dormitory).first() or profile_queryset.first() + else: + port_profile = profile_queryset.first() + return port_profile or Switch.nothing_profile + + @cached_property + def default_uplink_profile(self): + """Default uplink profile for that switch -- in cache""" + return self.profile_type_or_nothing('uplink') + + @cached_property + def default_access_point_profile(self): + """Default ap profile for that switch -- in cache""" + return self.profile_type_or_nothing('access_point') + + @cached_property + def default_room_profile(self): + """Default room profile for that switch -- in cache""" + return self.profile_type_or_nothing('room') + + @cached_property + def default_asso_machine_profile(self): + """Default asso machine profile for that switch -- in cache""" + return self.profile_type_or_nothing('asso_machine') + def __str__(self): return str(self.get_name) @@ -661,35 +705,20 @@ class Port(AclMixin, RevMixin, models.Model): elIf a default profile is defined for its dormitory, returns it Else, returns the global default profil If not exists, create a nothing profile""" - def profile_or_nothing(profile): - if self.switch.get_dormitory: - port_profile = PortProfile.objects.filter( - profil_default=profile).filter(on_dormitory=self.switch.get_dormitory).first() - if not port_profile: - port_profile = PortProfile.objects.filter(profil_default=profile).first() - if port_profile: - return port_profile - else: - nothing_profile, _created = PortProfile.objects.get_or_create( - profil_default='nothing', - name='nothing', - radius_type='NO' - ) - return nothing_profile if self.custom_profile: return self.custom_profile elif self.related: - return profile_or_nothing('uplink') + return self.switch.default_uplink_profile elif self.machine_interface: if hasattr(self.machine_interface.machine, 'accesspoint'): - return profile_or_nothing('access_point') + return self.switch.default_access_point_profile else: - return profile_or_nothing('asso_machine') + return self.switch.default_asso_machine_profile elif self.room: - return profile_or_nothing('room') + return self.switch.default_room_profile else: - return profile_or_nothing('nothing') + return Switch.nothing_profile @classmethod def get_instance(cls, portid, *_args, **kwargs): From 9882310d61a0ebdd191feb90b2e10e6463779ea2 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 27 Jul 2019 01:55:26 +0200 Subject: [PATCH 4/4] Affichage correct si port profile custom --- topologie/templates/topologie/aff_port.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/topologie/templates/topologie/aff_port.html b/topologie/templates/topologie/aff_port.html index 6a02b484..c789694e 100644 --- a/topologie/templates/topologie/aff_port.html +++ b/topologie/templates/topologie/aff_port.html @@ -88,7 +88,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} - {% if not port.custom_profil %} + {% if not port.custom_profile %} {% trans "Default: " %} {% endif %} {{ port.get_port_profile }}