mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 11:23:10 +00:00
PEP8 mon amour + typos
This commit is contained in:
parent
a07e0d922a
commit
eefa0b4add
4 changed files with 172 additions and 118 deletions
|
@ -355,7 +355,7 @@ def decide_vlan_and_register_switch(nas_machine, nas_type, port_number,
|
||||||
port=port_number
|
port=port_number
|
||||||
)
|
)
|
||||||
.first())
|
.first())
|
||||||
|
|
||||||
# Si le port est inconnu, on place sur le vlan defaut
|
# Si le port est inconnu, on place sur le vlan defaut
|
||||||
# Aucune information particulière ne permet de déterminer quelle
|
# Aucune information particulière ne permet de déterminer quelle
|
||||||
# politique à appliquer sur ce port
|
# politique à appliquer sur ce port
|
||||||
|
@ -363,12 +363,12 @@ def decide_vlan_and_register_switch(nas_machine, nas_type, port_number,
|
||||||
return (sw_name, "Chambre inconnue", u'Port inconnu', VLAN_OK)
|
return (sw_name, "Chambre inconnue", u'Port inconnu', VLAN_OK)
|
||||||
|
|
||||||
# On récupère le profil du port
|
# On récupère le profil du port
|
||||||
port_profil = port.get_port_profil
|
port_profile = port.get_port_profile
|
||||||
|
|
||||||
# Si un vlan a été précisé dans la config du port,
|
# Si un vlan a été précisé dans la config du port,
|
||||||
# on l'utilise pour VLAN_OK
|
# on l'utilise pour VLAN_OK
|
||||||
if port_profil.vlan_untagged:
|
if port_profile.vlan_untagged:
|
||||||
DECISION_VLAN = int(port_profil.vlan_untagged.vlan_id)
|
DECISION_VLAN = int(port_profile.vlan_untagged.vlan_id)
|
||||||
extra_log = u"Force sur vlan " + str(DECISION_VLAN)
|
extra_log = u"Force sur vlan " + str(DECISION_VLAN)
|
||||||
else:
|
else:
|
||||||
DECISION_VLAN = VLAN_OK
|
DECISION_VLAN = VLAN_OK
|
||||||
|
@ -378,7 +378,7 @@ def decide_vlan_and_register_switch(nas_machine, nas_type, port_number,
|
||||||
return (sw_name, port.room, u'Port desactivé', VLAN_NOK)
|
return (sw_name, port.room, u'Port desactivé', VLAN_NOK)
|
||||||
|
|
||||||
# Si radius est désactivé, on laisse passer
|
# Si radius est désactivé, on laisse passer
|
||||||
if port_profil.radius_type == 'NO':
|
if port_profile.radius_type == 'NO':
|
||||||
return (sw_name,
|
return (sw_name,
|
||||||
"",
|
"",
|
||||||
u"Pas d'authentification sur ce port" + extra_log,
|
u"Pas d'authentification sur ce port" + extra_log,
|
||||||
|
@ -386,7 +386,7 @@ def decide_vlan_and_register_switch(nas_machine, nas_type, port_number,
|
||||||
|
|
||||||
# Si le 802.1X est activé sur ce port, cela veut dire que la personne a été accept précédemment
|
# Si le 802.1X est activé sur ce port, cela veut dire que la personne a été accept précédemment
|
||||||
# Par conséquent, on laisse passer sur le bon vlan
|
# Par conséquent, on laisse passer sur le bon vlan
|
||||||
if nas_type.port_access_mode == '802.1X' and port_profil.radius_type == '802.1X':
|
if nas_type.port_access_mode == '802.1X' and port_profile.radius_type == '802.1X':
|
||||||
room = port.room or "Chambre/local inconnu"
|
room = port.room or "Chambre/local inconnu"
|
||||||
return (sw_name, room, u'Acceptation authentification 802.1X', DECISION_VLAN)
|
return (sw_name, room, u'Acceptation authentification 802.1X', DECISION_VLAN)
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ def decide_vlan_and_register_switch(nas_machine, nas_type, port_number,
|
||||||
# rattachés à ce port sont bien à jour de cotisation. Sinon on rejette (anti squattage)
|
# rattachés à ce port sont bien à jour de cotisation. Sinon on rejette (anti squattage)
|
||||||
# Il n'est pas possible de se connecter sur une prise strict sans adhérent à jour de cotis
|
# Il n'est pas possible de se connecter sur une prise strict sans adhérent à jour de cotis
|
||||||
# dedans
|
# dedans
|
||||||
if port_profil.radius_mode == 'STRICT':
|
if port_profile.radius_mode == 'STRICT':
|
||||||
room = port.room
|
room = port.room
|
||||||
if not room:
|
if not room:
|
||||||
return (sw_name, "Inconnue", u'Chambre inconnue', VLAN_NOK)
|
return (sw_name, "Inconnue", u'Chambre inconnue', VLAN_NOK)
|
||||||
|
@ -411,7 +411,7 @@ def decide_vlan_and_register_switch(nas_machine, nas_type, port_number,
|
||||||
# else: user OK, on passe à la verif MAC
|
# else: user OK, on passe à la verif MAC
|
||||||
|
|
||||||
# Si on fait de l'auth par mac, on cherche l'interface via sa mac dans la bdd
|
# Si on fait de l'auth par mac, on cherche l'interface via sa mac dans la bdd
|
||||||
if port_profil.radius_mode == 'COMMON' or port_profil.radius_mode == 'STRICT':
|
if port_profile.radius_mode == 'COMMON' or port_profile.radius_mode == 'STRICT':
|
||||||
# Authentification par mac
|
# Authentification par mac
|
||||||
interface = (Interface.objects
|
interface = (Interface.objects
|
||||||
.filter(mac_address=mac_address)
|
.filter(mac_address=mac_address)
|
||||||
|
|
|
@ -40,7 +40,7 @@ from __future__ import unicode_literals
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import pre_save, post_save, post_delete
|
from django.db.models.signals import post_save, post_delete
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
@ -52,11 +52,6 @@ from reversion import revisions as reversion
|
||||||
from machines.models import Machine, regen
|
from machines.models import Machine, regen
|
||||||
from re2o.mixins import AclMixin, RevMixin
|
from re2o.mixins import AclMixin, RevMixin
|
||||||
|
|
||||||
from os.path import isfile
|
|
||||||
from os import remove
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Stack(AclMixin, RevMixin, models.Model):
|
class Stack(AclMixin, RevMixin, models.Model):
|
||||||
"""Un objet stack. Regrouppe des switchs en foreign key
|
"""Un objet stack. Regrouppe des switchs en foreign key
|
||||||
|
@ -123,7 +118,10 @@ class AccessPoint(AclMixin, Machine):
|
||||||
)
|
)
|
||||||
|
|
||||||
def building(self):
|
def building(self):
|
||||||
"""Return the building of the AP/Server (building of the switchs connected to...)"""
|
"""
|
||||||
|
Return the building of the AP/Server (building of the switchs
|
||||||
|
connected to...)
|
||||||
|
"""
|
||||||
return Building.objects.filter(
|
return Building.objects.filter(
|
||||||
switchbay__switch=self.switch()
|
switchbay__switch=self.switch()
|
||||||
)
|
)
|
||||||
|
@ -135,14 +133,18 @@ class AccessPoint(AclMixin, Machine):
|
||||||
@classmethod
|
@classmethod
|
||||||
def all_ap_in(cls, building_instance):
|
def all_ap_in(cls, building_instance):
|
||||||
"""Get a building as argument, returns all ap of a building"""
|
"""Get a building as argument, returns all ap of a building"""
|
||||||
return cls.objects.filter(interface__port__switch__switchbay__building=building_instance)
|
return cls.objects.filter(
|
||||||
|
interface__port__switch__switchbay__building=building_instance
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.interface_set.first())
|
return str(self.interface_set.first())
|
||||||
|
|
||||||
|
|
||||||
class Server(Machine):
|
class Server(Machine):
|
||||||
"""Dummy class, to retrieve servers of a building, or get switch of a server"""
|
"""
|
||||||
|
Dummy class, to retrieve servers of a building, or get switch of a server
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
proxy = True
|
proxy = True
|
||||||
|
@ -160,7 +162,10 @@ class Server(Machine):
|
||||||
)
|
)
|
||||||
|
|
||||||
def building(self):
|
def building(self):
|
||||||
"""Return the building of the AP/Server (building of the switchs connected to...)"""
|
"""
|
||||||
|
Return the building of the AP/Server
|
||||||
|
(building of the switchs connected to...)
|
||||||
|
"""
|
||||||
return Building.objects.filter(
|
return Building.objects.filter(
|
||||||
switchbay__switch=self.switch()
|
switchbay__switch=self.switch()
|
||||||
)
|
)
|
||||||
|
@ -172,7 +177,9 @@ class Server(Machine):
|
||||||
@classmethod
|
@classmethod
|
||||||
def all_server_in(cls, building_instance):
|
def all_server_in(cls, building_instance):
|
||||||
"""Get a building as argument, returns all server of a building"""
|
"""Get a building as argument, returns all server of a building"""
|
||||||
return cls.objects.filter(interface__port__switch__switchbay__building=building_instance).exclude(accesspoint__isnull=False)
|
return cls.objects.filter(
|
||||||
|
interface__port__switch__switchbay__building=building_instance
|
||||||
|
).exclude(accesspoint__isnull=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.interface_set.first())
|
return str(self.interface_set.first())
|
||||||
|
@ -200,7 +207,7 @@ class Switch(AclMixin, Machine):
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
on_delete=models.SET_NULL
|
on_delete=models.SET_NULL
|
||||||
)
|
)
|
||||||
stack_member_id = models.PositiveIntegerField(
|
stack_member_id = models.PositiveIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
|
@ -238,7 +245,7 @@ class Switch(AclMixin, Machine):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{'stack_member_id': "L'id de ce switch est en\
|
{'stack_member_id': "L'id de ce switch est en\
|
||||||
dehors des bornes permises pas la stack"}
|
dehors des bornes permises pas la stack"}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ValidationError({'stack_member_id': "L'id dans la stack\
|
raise ValidationError({'stack_member_id': "L'id dans la stack\
|
||||||
ne peut être nul"})
|
ne peut être nul"})
|
||||||
|
@ -378,25 +385,25 @@ class Port(AclMixin, RevMixin, models.Model):
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
machine_interface = models.ForeignKey(
|
machine_interface = models.ForeignKey(
|
||||||
'machines.Interface',
|
'machines.Interface',
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
related = models.OneToOneField(
|
related = models.OneToOneField(
|
||||||
'self',
|
'self',
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='related_port'
|
related_name='related_port'
|
||||||
)
|
)
|
||||||
custom_profile = models.ForeignKey(
|
custom_profile = models.ForeignKey(
|
||||||
'PortProfile',
|
'PortProfile',
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
state = models.BooleanField(
|
state = models.BooleanField(
|
||||||
default=True,
|
default=True,
|
||||||
help_text='Port state Active',
|
help_text='Port state Active',
|
||||||
|
@ -411,32 +418,35 @@ class Port(AclMixin, RevMixin, models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def get_port_profil(self):
|
def get_port_profile(self):
|
||||||
"""Return the config profil for this port
|
"""Return the config profile for this port
|
||||||
:returns: the profile of self (port)"""
|
:returns: the profile of self (port)"""
|
||||||
def profil_or_nothing(profil):
|
def profile_or_nothing(profile):
|
||||||
port_profil = PortProfile.objects.filter(profil_default=profil).first()
|
port_profile = PortProfile.objects.filter(
|
||||||
if port_profil:
|
profile_default=profile).first()
|
||||||
return port_profil
|
if port_profile:
|
||||||
|
return port_profile
|
||||||
else:
|
else:
|
||||||
nothing = PortProfile.objects.filter(profil_default='nothing').first()
|
nothing_profile, _created = PortProfile.objects.get_or_create(
|
||||||
if not nothing:
|
profile_default='nothing',
|
||||||
nothing = PortProfile.objects.create(profil_default='nothing', name='nothing', radius_type='NO')
|
name='nothing',
|
||||||
return nothing
|
radius_type='NO'
|
||||||
|
)
|
||||||
|
return nothing_profile
|
||||||
|
|
||||||
if self.custom_profile:
|
if self.custom_profile:
|
||||||
return self.custom_profile
|
return self.custom_profile
|
||||||
elif self.related:
|
elif self.related:
|
||||||
return profil_or_nothing('uplink')
|
return profile_or_nothing('uplink')
|
||||||
elif self.machine_interface:
|
elif self.machine_interface:
|
||||||
if hasattr(self.machine_interface.machine, 'accesspoint'):
|
if hasattr(self.machine_interface.machine, 'accesspoint'):
|
||||||
return profil_or_nothing('access_point')
|
return profile_or_nothing('access_point')
|
||||||
else:
|
else:
|
||||||
return profil_or_nothing('asso_machine')
|
return profile_or_nothing('asso_machine')
|
||||||
elif self.room:
|
elif self.room:
|
||||||
return profil_or_nothing('room')
|
return profile_or_nothing('room')
|
||||||
else:
|
else:
|
||||||
return profil_or_nothing('nothing')
|
return profile_or_nothing('nothing')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_instance(cls, portid, *_args, **kwargs):
|
def get_instance(cls, portid, *_args, **kwargs):
|
||||||
|
@ -521,11 +531,11 @@ class PortProfile(AclMixin, RevMixin, models.Model):
|
||||||
('NO', 'NO'),
|
('NO', 'NO'),
|
||||||
('802.1X', '802.1X'),
|
('802.1X', '802.1X'),
|
||||||
('MAC-radius', 'MAC-radius'),
|
('MAC-radius', 'MAC-radius'),
|
||||||
)
|
)
|
||||||
MODES = (
|
MODES = (
|
||||||
('STRICT', 'STRICT'),
|
('STRICT', 'STRICT'),
|
||||||
('COMMON', 'COMMON'),
|
('COMMON', 'COMMON'),
|
||||||
)
|
)
|
||||||
SPEED = (
|
SPEED = (
|
||||||
('10-half', '10-half'),
|
('10-half', '10-half'),
|
||||||
('100-half', '100-half'),
|
('100-half', '100-half'),
|
||||||
|
@ -535,14 +545,14 @@ class PortProfile(AclMixin, RevMixin, models.Model):
|
||||||
('auto', 'auto'),
|
('auto', 'auto'),
|
||||||
('auto-10', 'auto-10'),
|
('auto-10', 'auto-10'),
|
||||||
('auto-100', 'auto-100'),
|
('auto-100', 'auto-100'),
|
||||||
)
|
)
|
||||||
PROFIL_DEFAULT= (
|
PROFIL_DEFAULT = (
|
||||||
('room', 'room'),
|
('room', 'room'),
|
||||||
('accespoint', 'accesspoint'),
|
('accespoint', 'accesspoint'),
|
||||||
('uplink', 'uplink'),
|
('uplink', 'uplink'),
|
||||||
('asso_machine', 'asso_machine'),
|
('asso_machine', 'asso_machine'),
|
||||||
('nothing', 'nothing'),
|
('nothing', 'nothing'),
|
||||||
)
|
)
|
||||||
name = models.CharField(max_length=255, verbose_name=_("Name"))
|
name = models.CharField(max_length=255, verbose_name=_("Name"))
|
||||||
profil_default = models.CharField(
|
profil_default = models.CharField(
|
||||||
max_length=32,
|
max_length=32,
|
||||||
|
@ -616,25 +626,36 @@ class PortProfile(AclMixin, RevMixin, models.Model):
|
||||||
default=False,
|
default=False,
|
||||||
help_text='Protect against rogue ra',
|
help_text='Protect against rogue ra',
|
||||||
verbose_name=_("Ra guard")
|
verbose_name=_("Ra guard")
|
||||||
)
|
)
|
||||||
loop_protect = models.BooleanField(
|
loop_protect = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
help_text='Protect again loop',
|
help_text='Protect again loop',
|
||||||
verbose_name=_("Loop Protect")
|
verbose_name=_("Loop Protect")
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
("view_port_profile", _("Can view a port profile object")),
|
("view_port_profile", _("Can view a port profile object")),
|
||||||
)
|
)
|
||||||
verbose_name = _("Port profile")
|
verbose_name = _("Port profile")
|
||||||
verbose_name_plural = _("Port profiles")
|
verbose_name_plural = _("Port profiles")
|
||||||
|
|
||||||
security_parameters_fields = ['loop_protect', 'ra_guard', 'arp_protect', 'dhcpv6_snooping', 'dhcp_snooping', 'flow_control']
|
security_parameters_fields = [
|
||||||
|
'loop_protect',
|
||||||
|
'ra_guard',
|
||||||
|
'arp_protect',
|
||||||
|
'dhcpv6_snooping',
|
||||||
|
'dhcp_snooping',
|
||||||
|
'flow_control'
|
||||||
|
]
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def security_parameters_enabled(self):
|
def security_parameters_enabled(self):
|
||||||
return [parameter for parameter in self.security_parameters_fields if getattr(self, parameter)]
|
return [
|
||||||
|
parameter
|
||||||
|
for parameter in self.security_parameters_fields
|
||||||
|
if getattr(self, parameter)
|
||||||
|
]
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def security_parameters_as_str(self):
|
def security_parameters_as_str(self):
|
||||||
|
@ -650,45 +671,55 @@ def ap_post_save(**_kwargs):
|
||||||
regen('unifi-ap-names')
|
regen('unifi-ap-names')
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=AccessPoint)
|
@receiver(post_delete, sender=AccessPoint)
|
||||||
def ap_post_delete(**_kwargs):
|
def ap_post_delete(**_kwargs):
|
||||||
"""Regeneration des noms des bornes vers le controleur"""
|
"""Regeneration des noms des bornes vers le controleur"""
|
||||||
regen('unifi-ap-names')
|
regen('unifi-ap-names')
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Stack)
|
@receiver(post_delete, sender=Stack)
|
||||||
def stack_post_delete(**_kwargs):
|
def stack_post_delete(**_kwargs):
|
||||||
"""Vide les id des switches membres d'une stack supprimée"""
|
"""Vide les id des switches membres d'une stack supprimée"""
|
||||||
Switch.objects.filter(stack=None).update(stack_member_id=None)
|
Switch.objects.filter(stack=None).update(stack_member_id=None)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Port)
|
@receiver(post_save, sender=Port)
|
||||||
def port_post_save(**_kwargs):
|
def port_post_save(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Port)
|
@receiver(post_delete, sender=Port)
|
||||||
def port_post_delete(**_kwargs):
|
def port_post_delete(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=ModelSwitch)
|
@receiver(post_save, sender=ModelSwitch)
|
||||||
def modelswitch_post_save(**_kwargs):
|
def modelswitch_post_save(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=ModelSwitch)
|
@receiver(post_delete, sender=ModelSwitch)
|
||||||
def modelswitch_post_delete(**_kwargs):
|
def modelswitch_post_delete(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Building)
|
@receiver(post_save, sender=Building)
|
||||||
def building_post_save(**_kwargs):
|
def building_post_save(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Building)
|
@receiver(post_delete, sender=Building)
|
||||||
def building_post_delete(**_kwargs):
|
def building_post_delete(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Switch)
|
@receiver(post_save, sender=Switch)
|
||||||
def switch_post_save(**_kwargs):
|
def switch_post_save(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Switch)
|
@receiver(post_delete, sender=Switch)
|
||||||
def switch_post_delete(**_kwargs):
|
def switch_post_delete(**_kwargs):
|
||||||
regen("graph_topo")
|
regen("graph_topo")
|
||||||
|
|
|
@ -29,9 +29,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% include "pagination.html" with list=port_profile_list %}
|
{% include "pagination.html" with list=port_profile_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<thead>
|
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Name" %}</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th>{% trans "Default for" %}</th>
|
<th>{% trans "Default for" %}</th>
|
||||||
|
@ -49,7 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<td>{{port_profile.profil_default}}</td>
|
<td>{{port_profile.profil_default}}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if port_profile.vlan_untagged %}
|
{% if port_profile.vlan_untagged %}
|
||||||
<b>Untagged : </b>{{port_profile.vlan_untagged}}
|
<b>Untagged : </b>{{port_profile.vlan_untagged}}
|
||||||
<br>
|
<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if port_profile.vlan_tagged.all %}
|
{% if port_profile.vlan_tagged.all %}
|
||||||
|
|
|
@ -42,11 +42,7 @@ from django.contrib.auth.decorators import login_required
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import ProtectedError, Prefetch
|
from django.db.models import ProtectedError, Prefetch
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
|
||||||
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.dispatch import receiver
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -105,8 +101,7 @@ from subprocess import (
|
||||||
PIPE
|
PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
from os.path import isfile
|
from os.path import isfile
|
||||||
from os import remove
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -128,13 +123,17 @@ def index(request):
|
||||||
SortTable.TOPOLOGIE_INDEX
|
SortTable.TOPOLOGIE_INDEX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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()
|
||||||
for service_link in Service_link.objects.filter(service__service_type='graph_topo'):
|
for service_link in Service_link.objects.filter(
|
||||||
|
service__service_type='graph_topo'):
|
||||||
service_link.done_regen()
|
service_link.done_regen()
|
||||||
|
|
||||||
if not isfile("/var/www/re2o/media/images/switchs.png"):
|
if not isfile("/var/www/re2o/media/images/switchs.png"):
|
||||||
|
@ -150,8 +149,10 @@ def index(request):
|
||||||
@can_view_all(PortProfile)
|
@can_view_all(PortProfile)
|
||||||
def index_port_profile(request):
|
def index_port_profile(request):
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
||||||
port_profile_list = PortProfile.objects.all().select_related('vlan_untagged')
|
port_profile_list = PortProfile.objects.all().select_related(
|
||||||
port_profile_list = re2o_paginator(request, port_profile_list, pagination_number)
|
'vlan_untagged')
|
||||||
|
port_profile_list = re2o_paginator(
|
||||||
|
request, port_profile_list, pagination_number)
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
'topologie/index_portprofile.html',
|
'topologie/index_portprofile.html',
|
||||||
|
@ -460,7 +461,7 @@ def new_switch(request):
|
||||||
)
|
)
|
||||||
domain = DomainForm(
|
domain = DomainForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
)
|
)
|
||||||
if switch.is_valid() and interface.is_valid():
|
if switch.is_valid() and interface.is_valid():
|
||||||
user = AssoOption.get_cached_value('utilisateur_asso')
|
user = AssoOption.get_cached_value('utilisateur_asso')
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -530,7 +531,7 @@ def create_ports(request, switchid):
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'topologie:index-port',
|
'topologie:index-port',
|
||||||
kwargs={'switchid': switchid}
|
kwargs={'switchid': switchid}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'id_switch': switchid, 'topoform': port_form},
|
{'id_switch': switchid, 'topoform': port_form},
|
||||||
'topologie/switch.html',
|
'topologie/switch.html',
|
||||||
|
@ -548,16 +549,16 @@ def edit_switch(request, switch, switchid):
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=switch,
|
instance=switch,
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
interface_form = EditInterfaceForm(
|
interface_form = EditInterfaceForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=switch.interface_set.first(),
|
instance=switch.interface_set.first(),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
domain_form = DomainForm(
|
domain_form = DomainForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=switch.interface_set.first().domain
|
instance=switch.interface_set.first().domain
|
||||||
)
|
)
|
||||||
if switch_form.is_valid() and interface_form.is_valid():
|
if switch_form.is_valid() and interface_form.is_valid():
|
||||||
new_switch_obj = switch_form.save(commit=False)
|
new_switch_obj = switch_form.save(commit=False)
|
||||||
new_interface_obj = interface_form.save(commit=False)
|
new_interface_obj = interface_form.save(commit=False)
|
||||||
|
@ -601,7 +602,7 @@ def new_ap(request):
|
||||||
)
|
)
|
||||||
domain = DomainForm(
|
domain = DomainForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
)
|
)
|
||||||
if ap.is_valid() and interface.is_valid():
|
if ap.is_valid() and interface.is_valid():
|
||||||
user = AssoOption.get_cached_value('utilisateur_asso')
|
user = AssoOption.get_cached_value('utilisateur_asso')
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -656,7 +657,7 @@ def edit_ap(request, ap, **_kwargs):
|
||||||
domain_form = DomainForm(
|
domain_form = DomainForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=ap.interface_set.first().domain
|
instance=ap.interface_set.first().domain
|
||||||
)
|
)
|
||||||
if ap_form.is_valid() and interface_form.is_valid():
|
if ap_form.is_valid() and interface_form.is_valid():
|
||||||
user = AssoOption.get_cached_value('utilisateur_asso')
|
user = AssoOption.get_cached_value('utilisateur_asso')
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -970,7 +971,7 @@ def del_constructor_switch(request, constructor_switch, **_kwargs):
|
||||||
return form({
|
return form({
|
||||||
'objet': constructor_switch,
|
'objet': constructor_switch,
|
||||||
'objet_name': 'Constructeur de switch'
|
'objet_name': 'Constructeur de switch'
|
||||||
}, 'topologie/delete.html', request)
|
}, 'topologie/delete.html', request)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -993,7 +994,8 @@ def new_port_profile(request):
|
||||||
@can_edit(PortProfile)
|
@can_edit(PortProfile)
|
||||||
def edit_port_profile(request, port_profile, **_kwargs):
|
def edit_port_profile(request, port_profile, **_kwargs):
|
||||||
"""Edit a port profile"""
|
"""Edit a port profile"""
|
||||||
port_profile = EditPortProfileForm(request.POST or None, instance=port_profile)
|
port_profile = EditPortProfileForm(
|
||||||
|
request.POST or None, instance=port_profile)
|
||||||
if port_profile.is_valid():
|
if port_profile.is_valid():
|
||||||
if port_profile.changed_data:
|
if port_profile.changed_data:
|
||||||
port_profile.save()
|
port_profile.save()
|
||||||
|
@ -1006,7 +1008,6 @@ def edit_port_profile(request, port_profile, **_kwargs):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_delete(PortProfile)
|
@can_delete(PortProfile)
|
||||||
def del_port_profile(request, port_profile, **_kwargs):
|
def del_port_profile(request, port_profile, **_kwargs):
|
||||||
|
@ -1014,25 +1015,26 @@ def del_port_profile(request, port_profile, **_kwargs):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
try:
|
try:
|
||||||
port_profile.delete()
|
port_profile.delete()
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
_("The port profile was successfully deleted"))
|
_("The port profile was successfully deleted"))
|
||||||
except ProtectedError:
|
except ProtectedError:
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
_("Impossible to delete the port profile"))
|
_("Impossible to delete the port profile"))
|
||||||
return redirect(reverse('topologie:index'))
|
return redirect(reverse('topologie:index'))
|
||||||
return form(
|
return form(
|
||||||
{'objet': port_profile, 'objet_name': _("Port profile")},
|
{'objet': port_profile, 'objet_name': _("Port profile")},
|
||||||
'topologie/delete.html',
|
'topologie/delete.html',
|
||||||
request
|
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.
|
||||||
"""
|
"""
|
||||||
dico = {
|
dico = {
|
||||||
'subs': [],
|
'subs': [],
|
||||||
'links' : [],
|
'links': [],
|
||||||
'alone': [],
|
'alone': [],
|
||||||
'colors': {
|
'colors': {
|
||||||
'head': "#7f0505", # Color parameters for the graph
|
'head': "#7f0505", # Color parameters for the graph
|
||||||
|
@ -1041,23 +1043,23 @@ def make_machine_graph():
|
||||||
'border_bornes': "#02078e",
|
'border_bornes': "#02078e",
|
||||||
'head_bornes': "#25771c",
|
'head_bornes': "#25771c",
|
||||||
'head_server': "#1c3777"
|
'head_server': "#1c3777"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
missing = list(Switch.objects.all())
|
missing = list(Switch.objects.all())
|
||||||
detected = []
|
detected = []
|
||||||
for building in Building.objects.all(): # Visit all buildings
|
for building in Building.objects.all(): # Visit all buildings
|
||||||
|
|
||||||
dico['subs'].append(
|
dico['subs'].append(
|
||||||
{
|
{
|
||||||
'bat_id': building.id,
|
'bat_id': building.id,
|
||||||
'bat_name': building,
|
'bat_name': building,
|
||||||
'switchs': [],
|
'switchs': [],
|
||||||
'bornes': [],
|
'bornes': [],
|
||||||
'machines': []
|
'machines': []
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# Visit all switchs in this building
|
# Visit all switchs in this building
|
||||||
for switch in Switch.objects.filter(switchbay__building=building):
|
for switch in Switch.objects.filter(switchbay__building=building):
|
||||||
dico['subs'][-1]['switchs'].append({
|
dico['subs'][-1]['switchs'].append({
|
||||||
'name': switch.main_interface().domain.name,
|
'name': switch.main_interface().domain.name,
|
||||||
'nombre': switch.number,
|
'nombre': switch.number,
|
||||||
|
@ -1067,7 +1069,7 @@ def make_machine_graph():
|
||||||
'ports': []
|
'ports': []
|
||||||
})
|
})
|
||||||
# visit all ports of this switch and add the switchs linked to it
|
# visit all ports of this switch and add the switchs linked to it
|
||||||
for port in switch.ports.filter(related__isnull=False):
|
for port in switch.ports.filter(related__isnull=False):
|
||||||
dico['subs'][-1]['switchs'][-1]['ports'].append({
|
dico['subs'][-1]['switchs'][-1]['ports'].append({
|
||||||
'numero': port.port,
|
'numero': port.port,
|
||||||
'related': port.related.switch.main_interface().domain.name
|
'related': port.related.switch.main_interface().domain.name
|
||||||
|
@ -1085,50 +1087,58 @@ def make_machine_graph():
|
||||||
dico['subs'][-1]['machines'].append({
|
dico['subs'][-1]['machines'].append({
|
||||||
'name': server.short_name,
|
'name': server.short_name,
|
||||||
'switch': server.switch()[0].main_interface().domain.name,
|
'switch': server.switch()[0].main_interface().domain.name,
|
||||||
'port': Port.objects.filter(machine_interface__machine=server)[0].port
|
'port': Port.objects.filter(
|
||||||
|
machine_interface__machine=server
|
||||||
|
)[0].port
|
||||||
})
|
})
|
||||||
|
|
||||||
# While the list of forgotten ones is not empty
|
# While the list of forgotten ones is not empty
|
||||||
while missing:
|
while missing:
|
||||||
if missing[0].ports.count(): # The switch is not empty
|
if missing[0].ports.count(): # The switch is not empty
|
||||||
links, new_detected = recursive_switchs(missing[0], None, [missing[0]])
|
links, new_detected = recursive_switchs(
|
||||||
|
missing[0], None, [missing[0]])
|
||||||
for link in links:
|
for link in links:
|
||||||
dico['links'].append(link)
|
dico['links'].append(link)
|
||||||
# Update the lists of missings and already detected switchs
|
# Update the lists of missings and already detected switchs
|
||||||
missing=[i for i in missing if i not in new_detected]
|
missing = [i for i in missing if i not in new_detected]
|
||||||
detected += new_detected
|
detected += new_detected
|
||||||
else: # If the switch have no ports, don't explore it and hop to the next one
|
# If the switch have no ports, don't explore it and hop to the next one
|
||||||
|
else:
|
||||||
del missing[0]
|
del missing[0]
|
||||||
# Switchs that are not connected or not in a building
|
# Switchs that are not connected or not in a building
|
||||||
for switch in Switch.objects.filter(switchbay__isnull=True).exclude(ports__related__isnull=False):
|
for switch in Switch.objects.filter(
|
||||||
|
switchbay__isnull=True).exclude(ports__related__isnull=False):
|
||||||
dico['alone'].append({
|
dico['alone'].append({
|
||||||
'id': switch.id,
|
'id': switch.id,
|
||||||
'name': switch.main_interface().domain.name
|
'name': switch.main_interface().domain.name
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# generate the dot file
|
||||||
|
dot_data = generate_dot(dico, 'topologie/graph_switch.dot')
|
||||||
|
|
||||||
dot_data=generate_dot(dico,'topologie/graph_switch.dot') # generate the dot file
|
# Create a temporary file to store the dot data
|
||||||
|
f = tempfile.NamedTemporaryFile(mode='w+', encoding='utf-8', delete=False)
|
||||||
f = tempfile.NamedTemporaryFile(mode='w+', encoding='utf-8', delete=False) # Create a temporary file to store the dot data
|
|
||||||
with f:
|
with f:
|
||||||
f.write(dot_data)
|
f.write(dot_data)
|
||||||
unflatten = Popen( # unflatten the graph to make it look better
|
unflatten = Popen( # unflatten the graph to make it look better
|
||||||
["unflatten","-l", "3", f.name],
|
["unflatten", "-l", "3", f.name],
|
||||||
stdout=PIPE
|
stdout=PIPE
|
||||||
)
|
)
|
||||||
image = Popen( # pipe the result of the first command into the second
|
Popen( # pipe the result of the first command into the second
|
||||||
["dot", "-Tpng", "-o", MEDIA_ROOT + "/images/switchs.png"],
|
["dot", "-Tpng", "-o", MEDIA_ROOT + "/images/switchs.png"],
|
||||||
stdin=unflatten.stdout,
|
stdin=unflatten.stdout,
|
||||||
stdout=PIPE
|
stdout=PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_dot(data,template):
|
|
||||||
|
def generate_dot(data, template):
|
||||||
"""create the dot file
|
"""create the dot file
|
||||||
:param data: dictionary passed to the template
|
:param data: dictionary passed to the template
|
||||||
:param template: path to the dot template
|
:param template: path to the dot template
|
||||||
:return: all the lines of the dot file"""
|
:return: all the lines of the dot file"""
|
||||||
t = loader.get_template(template)
|
t = loader.get_template(template)
|
||||||
if not isinstance(t, Template) and not (hasattr(t, 'template') and isinstance(t.template, Template)):
|
if not isinstance(t, Template) and \
|
||||||
|
not (hasattr(t, 'template') and isinstance(t.template, Template)):
|
||||||
raise Exception("Le template par défaut de Django n'est pas utilisé."
|
raise Exception("Le template par défaut de Django n'est pas utilisé."
|
||||||
"Cela peut mener à des erreurs de rendu."
|
"Cela peut mener à des erreurs de rendu."
|
||||||
"Vérifiez les paramètres")
|
"Vérifiez les paramètres")
|
||||||
|
@ -1136,27 +1146,40 @@ def generate_dot(data,template):
|
||||||
dot = t.render(c)
|
dot = t.render(c)
|
||||||
return(dot)
|
return(dot)
|
||||||
|
|
||||||
|
|
||||||
def recursive_switchs(switch_start, switch_before, detected):
|
def recursive_switchs(switch_start, switch_before, detected):
|
||||||
"""Visit the switch and travel to the switchs linked to it.
|
"""Visit the switch and travel to the switchs linked to it.
|
||||||
:param switch_start: the switch to begin the visit on
|
:param switch_start: the switch to begin the visit on
|
||||||
:param switch_before: the switch that you come from. None if switch_start is the first one
|
:param switch_before: the switch that you come from.
|
||||||
:param detected: list of all switchs already visited. None if switch_start is the first one
|
None if switch_start is the first one
|
||||||
:return: A list of all the links found and a list of all the switchs visited"""
|
:param detected: list of all switchs already visited.
|
||||||
|
None if switch_start is the first one
|
||||||
|
:return: A list of all the links found and a list of
|
||||||
|
all the switchs visited
|
||||||
|
"""
|
||||||
detected.append(switch_start)
|
detected.append(switch_start)
|
||||||
links_return=[] # list of dictionaries of the links to be detected
|
links_return = [] # list of dictionaries of the links to be detected
|
||||||
for port in switch_start.ports.filter(related__isnull=False): # create links to every switchs below
|
# create links to every switchs below
|
||||||
if port.related.switch != switch_before and port.related.switch != port.switch and port.related.switch not in detected: # Not the switch that we come from, not the current switch
|
for port in switch_start.ports.filter(related__isnull=False):
|
||||||
|
# Not the switch that we come from, not the current switch
|
||||||
|
if port.related.switch != switch_before \
|
||||||
|
and port.related.switch != port.switch \
|
||||||
|
and port.related.switch not in detected:
|
||||||
links = { # Dictionary of a link
|
links = { # Dictionary of a link
|
||||||
'depart':switch_start.id,
|
'depart': switch_start.id,
|
||||||
'arrive':port.related.switch.id
|
'arrive': port.related.switch.id
|
||||||
}
|
}
|
||||||
links_return.append(links) # Add current and below levels links
|
links_return.append(links) # Add current and below levels links
|
||||||
|
|
||||||
for port in switch_start.ports.filter(related__isnull=False): # go down on every related switchs
|
# go down on every related switchs
|
||||||
if port.related.switch not in detected: # The switch at the end of this link has not been visited
|
for port in switch_start.ports.filter(related__isnull=False):
|
||||||
links_down, detected = recursive_switchs(port.related.switch, switch_start, detected) # explore it and get the results
|
# The switch at the end of this link has not been visited
|
||||||
for link in links_down: # Add the non empty links to the current list
|
if port.related.switch not in detected:
|
||||||
|
# explore it and get the results
|
||||||
|
links_down, detected = recursive_switchs(
|
||||||
|
port.related.switch, switch_start, detected)
|
||||||
|
# Add the non empty links to the current list
|
||||||
|
for link in links_down:
|
||||||
if link:
|
if link:
|
||||||
links_return.append(link)
|
links_return.append(link)
|
||||||
return (links_return, detected)
|
return (links_return, detected)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue