mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-30 08:32:26 +00:00
Add or translate some docstrings in topologie/
This commit is contained in:
parent
d186449767
commit
7939a986d0
4 changed files with 363 additions and 264 deletions
|
@ -20,8 +20,8 @@
|
|||
# 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.
|
||||
"""
|
||||
Fichier définissant les administration des models dans l'interface admin
|
||||
"""topologie.admin
|
||||
The objects, fields and datastructures visible in the Django admin view.
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
@ -45,67 +45,67 @@ from .models import (
|
|||
|
||||
|
||||
class StackAdmin(VersionAdmin):
|
||||
"""Administration d'une stack de switches (inclus des switches)"""
|
||||
"""Admin class of stacks (includes switches)."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SwitchAdmin(VersionAdmin):
|
||||
"""Administration d'un switch"""
|
||||
"""Admin class of switches."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PortAdmin(VersionAdmin):
|
||||
"""Administration d'un port de switches"""
|
||||
"""Admin class of switch ports."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AccessPointAdmin(VersionAdmin):
|
||||
"""Administration d'une borne"""
|
||||
"""Admin class of APs."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class RoomAdmin(VersionAdmin):
|
||||
"""Administration d'un chambre"""
|
||||
"""Admin class of rooms."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ModelSwitchAdmin(VersionAdmin):
|
||||
"""Administration d'un modèle de switch"""
|
||||
"""Admin class of switch models."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ConstructorSwitchAdmin(VersionAdmin):
|
||||
"""Administration d'un constructeur d'un switch"""
|
||||
"""Admin class of switch constructors."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SwitchBayAdmin(VersionAdmin):
|
||||
"""Administration d'une baie de brassage"""
|
||||
"""Admin class of switch bays."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class BuildingAdmin(VersionAdmin):
|
||||
"""Administration d'un batiment"""
|
||||
"""Admin class of buildings."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class DormitoryAdmin(VersionAdmin):
|
||||
"""Administration d'une residence"""
|
||||
"""Admin class of dormitories."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PortProfileAdmin(VersionAdmin):
|
||||
"""Administration of a port profile"""
|
||||
"""Admin class of port profiles."""
|
||||
|
||||
pass
|
||||
|
||||
|
|
|
@ -20,14 +20,12 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""
|
||||
Un forms le plus simple possible pour les objets topologie de re2o.
|
||||
Forms for the topologie app of re2o.
|
||||
|
||||
Permet de créer et supprimer : un Port de switch, relié à un switch.
|
||||
|
||||
Permet de créer des stacks et d'y ajouter des switchs (StackForm)
|
||||
|
||||
Permet de créer, supprimer et editer un switch (EditSwitchForm,
|
||||
NewSwitchForm)
|
||||
The forms are used to:
|
||||
* create and delete switch ports, related to a switch.
|
||||
* create stacks and add switches to them (StackForm).
|
||||
* create, edit and delete a switch (NewSwitchForm, EditSwitchForm).
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
@ -59,8 +57,7 @@ from .models import (
|
|||
|
||||
|
||||
class PortForm(FormRevMixin, ModelForm):
|
||||
"""Formulaire pour la création d'un port d'un switch
|
||||
Relié directement au modèle port"""
|
||||
"""Form used to manage a switch's port."""
|
||||
|
||||
class Meta:
|
||||
model = Port
|
||||
|
@ -72,14 +69,11 @@ class PortForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditPortForm(FormRevMixin, ModelForm):
|
||||
"""Form pour l'édition d'un port de switche : changement des reglages
|
||||
radius ou vlan, ou attribution d'une chambre, autre port ou machine
|
||||
"""Form used to edit a switch's port: change in RADIUS or VLANs settings,
|
||||
assignement to a room, port or machine.
|
||||
|
||||
Un port est relié à une chambre, un autre port (uplink) ou une machine
|
||||
(serveur ou borne), mutuellement exclusif
|
||||
Optimisation sur les queryset pour machines et port_related pour
|
||||
optimiser le temps de chargement avec select_related (vraiment
|
||||
lent sans)"""
|
||||
A port is related to either a room, another port (uplink) or a machine (server or AP).
|
||||
"""
|
||||
|
||||
class Meta(PortForm.Meta):
|
||||
fields = [
|
||||
|
@ -106,8 +100,7 @@ class EditPortForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class AddPortForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'ajouter un port de switch. Voir EditPortForm pour plus
|
||||
d'informations"""
|
||||
"""Form used to add a switch's port. See EditPortForm."""
|
||||
|
||||
class Meta(PortForm.Meta):
|
||||
fields = [
|
||||
|
@ -139,8 +132,7 @@ class AddPortForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class StackForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'edition d'une stack : stack_id, et switches membres
|
||||
de la stack"""
|
||||
"""Form used to create and edit stacks."""
|
||||
|
||||
class Meta:
|
||||
model = Stack
|
||||
|
@ -152,8 +144,7 @@ class StackForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class AddAccessPointForm(NewMachineForm):
|
||||
"""Formulaire pour la création d'une borne
|
||||
Relié directement au modèle borne"""
|
||||
"""Form used to create access points."""
|
||||
|
||||
class Meta:
|
||||
model = AccessPoint
|
||||
|
@ -161,7 +152,7 @@ class AddAccessPointForm(NewMachineForm):
|
|||
|
||||
|
||||
class EditAccessPointForm(EditMachineForm):
|
||||
"""Edition d'une borne. Edition complète"""
|
||||
"""Form used to edit access points."""
|
||||
|
||||
class Meta:
|
||||
model = AccessPoint
|
||||
|
@ -169,7 +160,7 @@ class EditAccessPointForm(EditMachineForm):
|
|||
|
||||
|
||||
class EditSwitchForm(EditMachineForm):
|
||||
"""Permet d'éditer un switch : nom et nombre de ports"""
|
||||
"""Form used to edit switches."""
|
||||
|
||||
class Meta:
|
||||
model = Switch
|
||||
|
@ -177,15 +168,14 @@ class EditSwitchForm(EditMachineForm):
|
|||
|
||||
|
||||
class NewSwitchForm(NewMachineForm):
|
||||
"""Permet de créer un switch : emplacement, paramètres machine,
|
||||
membre d'un stack (option), nombre de ports (number)"""
|
||||
"""Form used to create a switch."""
|
||||
|
||||
class Meta(EditSwitchForm.Meta):
|
||||
fields = ["name", "switchbay", "number", "stack", "stack_member_id"]
|
||||
|
||||
|
||||
class EditRoomForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'éediter le nom et commentaire d'une prise murale"""
|
||||
"""Form used to edit a room."""
|
||||
|
||||
class Meta:
|
||||
model = Room
|
||||
|
@ -197,14 +187,14 @@ class EditRoomForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class CreatePortsForm(forms.Form):
|
||||
"""Permet de créer une liste de ports pour un switch."""
|
||||
"""Form used to create switch ports lists."""
|
||||
|
||||
begin = forms.IntegerField(label=_("Start:"), min_value=0)
|
||||
end = forms.IntegerField(label=_("End:"), min_value=0)
|
||||
|
||||
|
||||
class EditModelSwitchForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'éediter un modèle de switch : nom et constructeur"""
|
||||
"""Form used to edit switch models."""
|
||||
|
||||
members = forms.ModelMultipleChoiceField(Switch.objects.all(), required=False)
|
||||
|
||||
|
@ -226,7 +216,7 @@ class EditModelSwitchForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditConstructorSwitchForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'éediter le nom d'un constructeur"""
|
||||
"""Form used to edit switch constructors."""
|
||||
|
||||
class Meta:
|
||||
model = ConstructorSwitch
|
||||
|
@ -238,7 +228,7 @@ class EditConstructorSwitchForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditSwitchBayForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'éditer une baie de brassage"""
|
||||
"""Form used to edit switch bays."""
|
||||
|
||||
members = forms.ModelMultipleChoiceField(Switch.objects.all(), required=False)
|
||||
|
||||
|
@ -260,7 +250,7 @@ class EditSwitchBayForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditBuildingForm(FormRevMixin, ModelForm):
|
||||
"""Permet d'éditer le batiment"""
|
||||
"""Form used to edit buildings."""
|
||||
|
||||
class Meta:
|
||||
model = Building
|
||||
|
@ -272,7 +262,7 @@ class EditBuildingForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditDormitoryForm(FormRevMixin, ModelForm):
|
||||
"""Enable dormitory edition"""
|
||||
"""Form used to edit dormitories."""
|
||||
|
||||
class Meta:
|
||||
model = Dormitory
|
||||
|
@ -284,7 +274,7 @@ class EditDormitoryForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditPortProfileForm(FormRevMixin, ModelForm):
|
||||
"""Form to edit a port profile"""
|
||||
"""Form used to edit port profiles."""
|
||||
|
||||
class Meta:
|
||||
model = PortProfile
|
||||
|
@ -296,7 +286,7 @@ class EditPortProfileForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditModuleForm(FormRevMixin, ModelForm):
|
||||
"""Add and edit module instance"""
|
||||
"""Form used to add and edit switch modules."""
|
||||
|
||||
class Meta:
|
||||
model = ModuleSwitch
|
||||
|
@ -308,7 +298,7 @@ class EditModuleForm(FormRevMixin, ModelForm):
|
|||
|
||||
|
||||
class EditSwitchModuleForm(FormRevMixin, ModelForm):
|
||||
"""Add/edit a switch to a module"""
|
||||
"""Form used to add and edit modules related to a switch."""
|
||||
|
||||
class Meta:
|
||||
model = ModuleOnSwitch
|
||||
|
|
|
@ -21,18 +21,15 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""
|
||||
Definition des modèles de l'application topologie.
|
||||
Definition of models for the 'topologie' app.
|
||||
|
||||
On défini les models suivants :
|
||||
|
||||
- stack (id, id_min, id_max et nom) regrouppant les switches
|
||||
- switch : nom, nombre de port, et interface
|
||||
machine correspondante (mac, ip, etc) (voir machines.models.interface)
|
||||
- Port: relié à un switch parent par foreign_key, numero du port,
|
||||
relié de façon exclusive à un autre port, une machine
|
||||
(serveur ou borne) ou une prise murale
|
||||
- room : liste des prises murales, nom et commentaire de l'état de
|
||||
la prise
|
||||
The following models are defined:
|
||||
* stack (grouping switches): id, id_min, id_max and name
|
||||
* switch: name, number of ports, related interface and machine (MAC
|
||||
address, IP address etc.) (see machines.models.interface)
|
||||
* port: related to a switch by foreign_key, number of the port, related
|
||||
exclusively to another port, machine (server or AP) or room outlets
|
||||
* room: list of outlets, name and comments about the plug's state
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
@ -56,9 +53,15 @@ from re2o.mixins import AclMixin, RevMixin
|
|||
|
||||
|
||||
class Stack(AclMixin, RevMixin, models.Model):
|
||||
"""Un objet stack. Regrouppe des switchs en foreign key
|
||||
,contient une id de stack, un switch id min et max dans
|
||||
le stack"""
|
||||
"""Switch stack.
|
||||
|
||||
Attributes:
|
||||
name: the name of the stack.
|
||||
stack_id: the ID of the stack, as a text chosen by the user.
|
||||
details: the description to provide details about the stack.
|
||||
member_id_min: the minimum switch ID in the stack.
|
||||
member_id_max: the maximum switch ID in the stack.
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=32, blank=True, null=True)
|
||||
stack_id = models.CharField(max_length=32, unique=True)
|
||||
|
@ -89,9 +92,10 @@ class Stack(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class AccessPoint(Machine):
|
||||
"""Define a wireless AP. Inherit from machines.interfaces
|
||||
"""Wireless Access Point. Inherits from machines.interfaces.
|
||||
|
||||
Definition pour une borne wifi , hérite de machines.interfaces
|
||||
Attributes:
|
||||
location: the text to provide details about the AP's location.
|
||||
"""
|
||||
|
||||
location = models.CharField(
|
||||
|
@ -107,17 +111,16 @@ class AccessPoint(Machine):
|
|||
verbose_name_plural = _("access points")
|
||||
|
||||
def port(self):
|
||||
"""Return the queryset of ports for this device"""
|
||||
"""Return the queryset of ports for this device."""
|
||||
return Port.objects.filter(machine_interface__machine=self)
|
||||
|
||||
def switch(self):
|
||||
"""Return the switch where this is plugged"""
|
||||
"""Return the switch where this is plugged."""
|
||||
return Switch.objects.filter(ports__machine_interface__machine=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 switches
|
||||
connected to...).
|
||||
"""
|
||||
return Building.objects.filter(switchbay__switch=self.switch())
|
||||
|
||||
|
@ -127,7 +130,14 @@ class AccessPoint(Machine):
|
|||
|
||||
@classmethod
|
||||
def all_ap_in(cls, building_instance):
|
||||
"""Get a building as argument, returns all ap of a building"""
|
||||
"""Get all the APs of the given building.
|
||||
|
||||
Args:
|
||||
building_instance: the building used to find APs.
|
||||
|
||||
Returns:
|
||||
The queryset of all APs in the given building.
|
||||
"""
|
||||
return cls.objects.filter(
|
||||
interface__port__switch__switchbay__building=building_instance
|
||||
)
|
||||
|
@ -158,25 +168,24 @@ class AccessPoint(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:
|
||||
proxy = True
|
||||
|
||||
def port(self):
|
||||
"""Return the queryset of ports for this device"""
|
||||
"""Return the queryset of ports for this device."""
|
||||
return Port.objects.filter(machine_interface__machine=self)
|
||||
|
||||
def switch(self):
|
||||
"""Return the switch where this is plugged"""
|
||||
"""Return the switch where this is plugged."""
|
||||
return Switch.objects.filter(ports__machine_interface__machine=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 switches
|
||||
connected to...).
|
||||
"""
|
||||
return Building.objects.filter(switchbay__switch=self.switch())
|
||||
|
||||
|
@ -186,7 +195,14 @@ class Server(Machine):
|
|||
|
||||
@classmethod
|
||||
def all_server_in(cls, building_instance):
|
||||
"""Get a building as argument, returns all server of a building"""
|
||||
"""Get all the servers of the given building.
|
||||
|
||||
Args:
|
||||
building_instance: the building used to find servers.
|
||||
|
||||
Returns:
|
||||
The queryset of all servers in the given building.
|
||||
"""
|
||||
return cls.objects.filter(
|
||||
interface__port__switch__switchbay__building=building_instance
|
||||
).exclude(accesspoint__isnull=False)
|
||||
|
@ -217,17 +233,19 @@ class Server(Machine):
|
|||
|
||||
|
||||
class Switch(Machine):
|
||||
""" Definition d'un switch. Contient un nombre de ports (number),
|
||||
un emplacement (location), un stack parent (optionnel, stack)
|
||||
et un id de membre dans le stack (stack_member_id)
|
||||
relié en onetoone à une interface
|
||||
Pourquoi ne pas avoir fait hériter switch de interface ?
|
||||
Principalement par méconnaissance de la puissance de cette façon de faire.
|
||||
Ceci étant entendu, django crée en interne un onetoone, ce qui a un
|
||||
effet identique avec ce que l'on fait ici
|
||||
"""Switch.
|
||||
|
||||
Validation au save que l'id du stack est bien dans le range id_min
|
||||
id_max de la stack parente"""
|
||||
Attributes:
|
||||
number: the number of ports of the switch.
|
||||
stack: the stack the switch is a part of.
|
||||
stack_member_id: the ID of the switch in the related stack.
|
||||
model: the model of the switch.
|
||||
switchbay: the bay in which the switch is located.
|
||||
radius_key: the RADIUS key of the switch.
|
||||
management_creds: the management credentials of the switch.
|
||||
automatic_provision: whether automatic provision is enabled for the
|
||||
switch.
|
||||
"""
|
||||
|
||||
number = models.PositiveIntegerField(help_text=_("Number of ports."))
|
||||
stack = models.ForeignKey(
|
||||
|
@ -269,8 +287,9 @@ class Switch(Machine):
|
|||
verbose_name_plural = _("switches")
|
||||
|
||||
def clean(self):
|
||||
""" Verifie que l'id stack est dans le bon range
|
||||
Appelle également le clean de la classe parente"""
|
||||
"""Check if the stack member ID is in the range of the stack's IDs and
|
||||
calls the clean of the parent class.
|
||||
"""
|
||||
super(Switch, self).clean()
|
||||
if self.stack is not None:
|
||||
if self.stack_member_id is not None:
|
||||
|
@ -293,6 +312,12 @@ class Switch(Machine):
|
|||
def create_ports(self, begin, end):
|
||||
""" Crée les ports de begin à end si les valeurs données
|
||||
sont cohérentes. """
|
||||
"""Create ports for the switch if the values are consistent.
|
||||
|
||||
Args:
|
||||
begin: the number of the start port.
|
||||
end: the number of the end port.
|
||||
"""
|
||||
if end < begin:
|
||||
raise ValidationError(_("The end port is less than the start port."))
|
||||
ports_to_create = range(begin, end + 1)
|
||||
|
@ -313,8 +338,7 @@ class Switch(Machine):
|
|||
)
|
||||
|
||||
def main_interface(self):
|
||||
""" Returns the 'main' interface of the switch
|
||||
It must the the management interface for that device"""
|
||||
"""Get the main interface of the switch (the management interface)."""
|
||||
switch_iptype = OptionalTopologie.get_cached_value("switchs_ip_type")
|
||||
if switch_iptype:
|
||||
return (
|
||||
|
@ -329,12 +353,14 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def get_radius_key(self):
|
||||
"""Retourne l'objet de la clef radius de ce switch"""
|
||||
"""Get the RADIUS key object related to the switch."""
|
||||
return self.radius_key or RadiusKey.objects.filter(default_switch=True).first()
|
||||
|
||||
@cached_property
|
||||
def get_radius_key_value(self):
|
||||
"""Retourne la valeur en str de la clef radius, none si il n'y en a pas"""
|
||||
"""Get the RADIUS key as a string, or None if there are no RADIUS key
|
||||
related to the switch.
|
||||
"""
|
||||
if self.get_radius_key:
|
||||
return self.get_radius_key.radius_key
|
||||
else:
|
||||
|
@ -362,7 +388,7 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def get_management_cred(self):
|
||||
"""Retourne l'objet des creds de managament de ce switch"""
|
||||
"""Get the management credentials objects of the switch."""
|
||||
return (
|
||||
self.management_creds
|
||||
or SwitchManagementCred.objects.filter(default_switch=True).first()
|
||||
|
@ -370,7 +396,9 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def get_management_cred_value(self):
|
||||
"""Retourne un dict des creds de management du switch"""
|
||||
"""Get the management credentials as a dictionary, or None if there are
|
||||
no management credentials related to the switch.
|
||||
"""
|
||||
if self.get_management_cred:
|
||||
return {
|
||||
"id": self.get_management_cred.management_id,
|
||||
|
@ -401,17 +429,19 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def ipv4(self):
|
||||
"""Return the switch's management ipv4"""
|
||||
"""Get the IPv4 address of the switch's management interface."""
|
||||
return str(self.main_interface().ipv4)
|
||||
|
||||
@cached_property
|
||||
def ipv6(self):
|
||||
"""Returne the switch's management ipv6"""
|
||||
"""Get the IPv6 address of the switch's management interface."""
|
||||
return str(self.main_interface().ipv6().first())
|
||||
|
||||
@cached_property
|
||||
def interfaces_subnet(self):
|
||||
"""Return dict ip:subnet for all ip of the switch"""
|
||||
"""Get a dictionary of IPv4 addresses:subnets of all the switch's
|
||||
interfaces.
|
||||
"""
|
||||
return dict(
|
||||
(
|
||||
str(interface.ipv4),
|
||||
|
@ -423,7 +453,9 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def interfaces6_subnet(self):
|
||||
"""Return dict ip6:subnet for all ipv6 of the switch"""
|
||||
"""Get a dictionary of IPv6 addresses:subnets of all the switch's
|
||||
interfaces.
|
||||
"""
|
||||
return dict(
|
||||
(
|
||||
str(interface.ipv6().first()),
|
||||
|
@ -434,7 +466,9 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def list_modules(self):
|
||||
"""Return modules of that switch, list of dict (rank, reference)"""
|
||||
"""Get the list of dictionaries (rank, reference) of modules related to
|
||||
the switch.
|
||||
"""
|
||||
modules = []
|
||||
if getattr(self.model, "is_modular", None):
|
||||
if self.model.is_itself_module:
|
||||
|
@ -445,7 +479,7 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def get_dormitory(self):
|
||||
"""Returns the dormitory of that switch"""
|
||||
"""Get the dormitory in which the switch is located."""
|
||||
if self.switchbay:
|
||||
return self.switchbay.building.dormitory
|
||||
else:
|
||||
|
@ -453,19 +487,19 @@ class Switch(Machine):
|
|||
|
||||
@classmethod
|
||||
def nothing_profile(cls):
|
||||
"""Return default nothing port profile"""
|
||||
"""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
|
||||
"""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"""
|
||||
If it exists, return the defined default profile for a profile type on
|
||||
the dormitory which the switch belongs.
|
||||
Otherwise, return the nothing profile.
|
||||
"""
|
||||
profile_queryset = PortProfile.objects.filter(profil_default=profile_type)
|
||||
if self.get_dormitory:
|
||||
port_profile = (
|
||||
|
@ -478,22 +512,22 @@ class Switch(Machine):
|
|||
|
||||
@cached_property
|
||||
def default_uplink_profile(self):
|
||||
"""Default uplink profile for that switch -- in cache"""
|
||||
"""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"""
|
||||
"""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"""
|
||||
"""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"""
|
||||
"""Default asso machine profile for that switch -- in cache."""
|
||||
return self.profile_type_or_nothing("asso_machine")
|
||||
|
||||
def __str__(self):
|
||||
|
@ -522,7 +556,16 @@ class Switch(Machine):
|
|||
|
||||
|
||||
class ModelSwitch(AclMixin, RevMixin, models.Model):
|
||||
"""Un modèle (au sens constructeur) de switch"""
|
||||
"""Switch model.
|
||||
|
||||
Attributes:
|
||||
reference: the reference of the switch model.
|
||||
commercial_name: the commercial name of the switch model.
|
||||
constructor: the constructor of the switch model.
|
||||
firmware: the firmware of the switch model.
|
||||
is_modular: whether the switch model is modular.
|
||||
is_itself_module: whether the switch is considered as a module.
|
||||
"""
|
||||
|
||||
reference = models.CharField(max_length=255)
|
||||
commercial_name = models.CharField(max_length=255, null=True, blank=True)
|
||||
|
@ -550,7 +593,12 @@ class ModelSwitch(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class ModuleSwitch(AclMixin, RevMixin, models.Model):
|
||||
"""A module of a switch"""
|
||||
"""Switch module.
|
||||
|
||||
Attributes:
|
||||
reference: the reference of the switch module.
|
||||
comment: the comment to describe the switch module.
|
||||
"""
|
||||
|
||||
reference = models.CharField(
|
||||
max_length=255,
|
||||
|
@ -575,7 +623,13 @@ class ModuleSwitch(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class ModuleOnSwitch(AclMixin, RevMixin, models.Model):
|
||||
"""Link beetween module and switch"""
|
||||
"""Link beetween module and switch.
|
||||
|
||||
Attributes:
|
||||
module: the switch module related to the link.
|
||||
switch: the switch related to the link.
|
||||
slot: the slot on the switch related to the link.
|
||||
"""
|
||||
|
||||
module = models.ForeignKey("ModuleSwitch", on_delete=models.CASCADE)
|
||||
switch = models.ForeignKey("Switch", on_delete=models.CASCADE)
|
||||
|
@ -601,7 +655,11 @@ class ModuleOnSwitch(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class ConstructorSwitch(AclMixin, RevMixin, models.Model):
|
||||
"""Un constructeur de switch"""
|
||||
"""Switch constructor.
|
||||
|
||||
Attributes:
|
||||
name: the name of the switch constructor.
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
|
@ -617,7 +675,13 @@ class ConstructorSwitch(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class SwitchBay(AclMixin, RevMixin, models.Model):
|
||||
"""Une baie de brassage"""
|
||||
"""Switch bay.
|
||||
|
||||
Attributes:
|
||||
name: the name of the switch bay.
|
||||
building: the building in which the switch bay is located.
|
||||
info: the information to describe to switch bay.
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
building = models.ForeignKey("Building", on_delete=models.PROTECT)
|
||||
|
@ -633,8 +697,11 @@ class SwitchBay(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class Dormitory(AclMixin, RevMixin, models.Model):
|
||||
"""A student accomodation/dormitory
|
||||
Une résidence universitaire"""
|
||||
"""Dormitory.
|
||||
|
||||
Attributes:
|
||||
name: the name of the dormitory.
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
|
@ -644,7 +711,7 @@ class Dormitory(AclMixin, RevMixin, models.Model):
|
|||
verbose_name_plural = _("dormitories")
|
||||
|
||||
def all_ap_in(self):
|
||||
"""Returns all ap of the dorms"""
|
||||
"""Get all the APs in the dormitory."""
|
||||
return AccessPoint.all_ap_in(self.building_set.all())
|
||||
|
||||
@classmethod
|
||||
|
@ -660,8 +727,13 @@ class Dormitory(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class Building(AclMixin, RevMixin, models.Model):
|
||||
"""A building of a dormitory
|
||||
Un batiment"""
|
||||
"""Building.
|
||||
|
||||
Attributes:
|
||||
name: the name of the building.
|
||||
dormitory: the dormitory of the building (a Dormitory can contain
|
||||
multiple dormitories).
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
dormitory = models.ForeignKey("Dormitory", on_delete=models.PROTECT)
|
||||
|
@ -672,7 +744,7 @@ class Building(AclMixin, RevMixin, models.Model):
|
|||
verbose_name_plural = _("buildings")
|
||||
|
||||
def all_ap_in(self):
|
||||
"""Returns all ap of the building"""
|
||||
"""Get all the APs in the building."""
|
||||
return AccessPoint.all_ap_in(self)
|
||||
|
||||
def get_name(self):
|
||||
|
@ -690,21 +762,32 @@ class Building(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class Port(AclMixin, RevMixin, models.Model):
|
||||
""" Definition d'un port. Relié à un switch(foreign_key),
|
||||
un port peut etre relié de manière exclusive à :
|
||||
- une chambre (room)
|
||||
- une machine (serveur etc) (machine_interface)
|
||||
- un autre port (uplink) (related)
|
||||
Champs supplémentaires :
|
||||
- RADIUS (mode STRICT : connexion sur port uniquement si machine
|
||||
d'un adhérent à jour de cotisation et que la chambre est également à
|
||||
jour de cotisation
|
||||
mode COMMON : vérification uniquement du statut de la machine
|
||||
mode NO : accepte toute demande venant du port et place sur le vlan normal
|
||||
mode BLOQ : rejet de toute authentification
|
||||
- vlan_force : override la politique générale de placement vlan, permet
|
||||
de forcer un port sur un vlan particulier. S'additionne à la politique
|
||||
RADIUS"""
|
||||
"""Port of a switch.
|
||||
|
||||
A port is related exclusively to either:
|
||||
* a room
|
||||
* a machine, e.g. server
|
||||
* another port
|
||||
Behaviour according to the RADIUS mode:
|
||||
* STRICT: connection only if the machine and room have access
|
||||
* COMMON: check only the machine's state
|
||||
* NO: accept only request coming from the port and set on the standard
|
||||
VLAN.
|
||||
* BLOQ: reject all requests.
|
||||
The VLAN can be forced to override the general policy for VLAN setting.
|
||||
This enables to force a port to a particular VLAN. It adds to the RADIUS
|
||||
policy.
|
||||
|
||||
Attributes:
|
||||
switch: the switch to which the port belongs.
|
||||
port: the port number on the switch for the Port object.
|
||||
room: the room to which the port is related.
|
||||
machine_interface: the machine to which the port is related
|
||||
related: the other port to which is port is related.
|
||||
custom_profile: the port profile of the port.
|
||||
state: whether the port is active.
|
||||
details: the details to describre the port.
|
||||
"""
|
||||
|
||||
switch = models.ForeignKey("Switch", related_name="ports", on_delete=models.CASCADE)
|
||||
port = models.PositiveIntegerField()
|
||||
|
@ -733,7 +816,7 @@ class Port(AclMixin, RevMixin, models.Model):
|
|||
|
||||
@cached_property
|
||||
def pretty_name(self):
|
||||
"""More elaborated name for label on switch conf"""
|
||||
"""More elaborated name for label on switch configuration."""
|
||||
if self.related:
|
||||
return _("Uplink: ") + self.related.switch.short_name
|
||||
elif self.machine_interface:
|
||||
|
@ -745,14 +828,13 @@ 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)
|
||||
|
||||
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"""
|
||||
"""Get the configuration profile for this port.
|
||||
|
||||
Returns:
|
||||
The custom profile if it exists, else the default profile of the
|
||||
dormitory if it exists, else the global default profile, else the
|
||||
nothing profile.
|
||||
"""
|
||||
if self.custom_profile:
|
||||
return self.custom_profile
|
||||
elif self.related:
|
||||
|
@ -779,26 +861,25 @@ class Port(AclMixin, RevMixin, models.Model):
|
|||
)
|
||||
|
||||
def make_port_related(self):
|
||||
""" Synchronise le port distant sur self"""
|
||||
"""Synchronise the related port with self."""
|
||||
related_port = self.related
|
||||
related_port.related = self
|
||||
related_port.save()
|
||||
|
||||
def clean_port_related(self):
|
||||
""" Supprime la relation related sur self"""
|
||||
"""Delete the related relation on self."""
|
||||
related_port = self.related_port
|
||||
related_port.related = None
|
||||
related_port.save()
|
||||
|
||||
def clean(self):
|
||||
""" Verifie que un seul de chambre, interface_parent et related_port
|
||||
est rempli. Verifie que le related n'est pas le port lui-même....
|
||||
Verifie que le related n'est pas déjà occupé par une machine ou une
|
||||
chambre. Si ce n'est pas le cas, applique la relation related
|
||||
Si un port related point vers self, on nettoie la relation
|
||||
A priori pas d'autre solution que de faire ça à la main. A priori
|
||||
tout cela est dans un bloc transaction, donc pas de problème de
|
||||
cohérence"""
|
||||
"""
|
||||
Check if the port is only related exclusively to either a room, a
|
||||
machine or another port.
|
||||
Check if the related port is not self and applies the relation to the
|
||||
related port if the relation is correct.
|
||||
Delete the relation if it points to self.
|
||||
"""
|
||||
if hasattr(self, "switch"):
|
||||
if self.port > self.switch.number:
|
||||
raise ValidationError(
|
||||
|
@ -835,7 +916,13 @@ class Port(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class Room(AclMixin, RevMixin, models.Model):
|
||||
"""Une chambre/local contenant une prise murale"""
|
||||
"""Room.
|
||||
|
||||
Attributes:
|
||||
name: the name of the room.
|
||||
details: the details describing the room.
|
||||
building: the building in which the room is located.
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
details = models.CharField(max_length=255, blank=True)
|
||||
|
@ -853,7 +940,28 @@ class Room(AclMixin, RevMixin, models.Model):
|
|||
|
||||
|
||||
class PortProfile(AclMixin, RevMixin, models.Model):
|
||||
"""Contains the information of the ports' configuration for a switch"""
|
||||
"""Port profile.
|
||||
|
||||
Contains the information of the ports' configuration for a switch.
|
||||
|
||||
Attributes:
|
||||
name: the name of the port profile.
|
||||
profil_default: the type of default profile (room, AP, uplink etc.).
|
||||
on_dormitory: the dormitory with this default port profile.
|
||||
vlan_untagged: the VLAN untagged of the port profile.
|
||||
vlan_tagged: the VLAN(s) tagged of the port profile.
|
||||
radius_type: the type of RADIUS authentication (inactive, MAC-address
|
||||
or 802.1X) of the port profile.
|
||||
radius_mode: the RADIUS mode of the port profile.
|
||||
speed: the port speed limit of the port profile.
|
||||
mac_limit: the MAC limit of the port profile.
|
||||
flow_control: whether flow control is enabled.
|
||||
dhcp_snooping: whether DHCP snooping is enabled.
|
||||
dhcpv6_snooping: whether DHCPv6 snooping is enabled.
|
||||
arp_protect: whether ARP protection is enabled.
|
||||
ra_guard: whether RA guard is enabled.
|
||||
loop_protect: whether loop protection is enabled.
|
||||
"""
|
||||
|
||||
TYPES = (("NO", "NO"), ("802.1X", "802.1X"), ("MAC-radius", _("MAC-RADIUS")))
|
||||
MODES = (("STRICT", "STRICT"), ("COMMON", "COMMON"))
|
||||
|
@ -983,7 +1091,7 @@ class PortProfile(AclMixin, RevMixin, models.Model):
|
|||
return ",".join(self.security_parameters_enabled)
|
||||
|
||||
def clean(self):
|
||||
""" Check that there is only one generic profil default"""
|
||||
"""Check that there is only one generic profile default."""
|
||||
super(PortProfile, self).clean()
|
||||
if (
|
||||
self.profil_default
|
||||
|
@ -1007,21 +1115,21 @@ class PortProfile(AclMixin, RevMixin, models.Model):
|
|||
|
||||
@receiver(post_save, sender=AccessPoint)
|
||||
def ap_post_save(**_kwargs):
|
||||
"""Regeneration des noms des bornes vers le controleur"""
|
||||
"""Regenerate the AP names towards the controller."""
|
||||
regen("unifi-ap-names")
|
||||
regen("graph_topo")
|
||||
|
||||
|
||||
@receiver(post_delete, sender=AccessPoint)
|
||||
def ap_post_delete(**_kwargs):
|
||||
"""Regeneration des noms des bornes vers le controleur"""
|
||||
"""Regenerate the AP names towards the controller."""
|
||||
regen("unifi-ap-names")
|
||||
regen("graph_topo")
|
||||
|
||||
|
||||
@receiver(post_delete, sender=Stack)
|
||||
def stack_post_delete(**_kwargs):
|
||||
"""Vide les id des switches membres d'une stack supprimée"""
|
||||
"""Empty the stack member ID of switches when a stack is deleted."""
|
||||
Switch.objects.filter(stack=None).update(stack_member_id=None)
|
||||
|
||||
|
||||
|
|
|
@ -20,18 +20,17 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
"""
|
||||
Page des vues de l'application topologie
|
||||
Views for the 'topologie' app of re2o.
|
||||
|
||||
Permet de créer, modifier et supprimer :
|
||||
- un port (add_port, edit_port, del_port)
|
||||
- un switch : les vues d'ajout et d'édition font appel aux forms de creation
|
||||
de switch, mais aussi aux forms de machines.forms (domain, interface et
|
||||
machine). Le views les envoie et les save en même temps. TODO : rationaliser
|
||||
et faire que la creation de machines (interfaces, domain etc) soit gérée
|
||||
coté models et forms de topologie
|
||||
- une chambre (new_room, edit_room, del_room)
|
||||
- une stack
|
||||
- l'historique de tous les objets cités
|
||||
They are used to create, edit and delete:
|
||||
* a port (add_port, edit_port, del_port)
|
||||
* a switch: the views call forms for switches but also machines (domain,
|
||||
interface and machine), send and save them at the same time.
|
||||
TODO rationalise, enforce the creation of machines (interfaces, domains
|
||||
etc.) in models and forms from 'topologie'
|
||||
* a room (new_room, edit_room, del_room)
|
||||
* a stack
|
||||
* histories of all objects mentioned.
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -105,7 +104,7 @@ from os.path import isfile
|
|||
@login_required
|
||||
@can_view_all(Switch)
|
||||
def index(request):
|
||||
""" Vue d'affichage de tous les swicthes"""
|
||||
"""View used to display all switches."""
|
||||
switch_list = (
|
||||
Switch.objects.prefetch_related(
|
||||
Prefetch(
|
||||
|
@ -171,7 +170,7 @@ def index_port_profile(request):
|
|||
@can_view_all(Port)
|
||||
@can_view(Switch)
|
||||
def index_port(request, switch, switchid):
|
||||
""" Affichage de l'ensemble des ports reliés à un switch particulier"""
|
||||
"""View used to display all ports related to the given switch."""
|
||||
port_list = (
|
||||
Port.objects.filter(switch=switch)
|
||||
.select_related("room__building__dormitory")
|
||||
|
@ -204,7 +203,7 @@ def index_port(request, switch, switchid):
|
|||
@login_required
|
||||
@can_view_all(Room)
|
||||
def index_room(request):
|
||||
""" Affichage de l'ensemble des chambres"""
|
||||
"""View used to display all rooms."""
|
||||
room_list = Room.objects.select_related("building__dormitory")
|
||||
room_list = SortTable.sort(
|
||||
room_list,
|
||||
|
@ -220,7 +219,7 @@ def index_room(request):
|
|||
@login_required
|
||||
@can_view_all(AccessPoint)
|
||||
def index_ap(request):
|
||||
""" Affichage de l'ensemble des bornes"""
|
||||
"""View used to display all APs."""
|
||||
ap_list = AccessPoint.objects.prefetch_related(
|
||||
Prefetch(
|
||||
"interface_set",
|
||||
|
@ -245,7 +244,7 @@ def index_ap(request):
|
|||
@login_required
|
||||
@can_view_all(Stack, Building, Dormitory, SwitchBay)
|
||||
def index_physical_grouping(request):
|
||||
"""Affichage de la liste des stacks (affiche l'ensemble des switches)"""
|
||||
"""View used to display the list of stacks (display all switches)."""
|
||||
stack_list = Stack.objects.prefetch_related(
|
||||
"switch_set__interface_set__domain__extension"
|
||||
)
|
||||
|
@ -293,7 +292,7 @@ def index_physical_grouping(request):
|
|||
@login_required
|
||||
@can_view_all(ModelSwitch, ConstructorSwitch)
|
||||
def index_model_switch(request):
|
||||
""" Affichage de l'ensemble des modèles de switches"""
|
||||
"""View used to display all switch models."""
|
||||
model_switch_list = ModelSwitch.objects.select_related(
|
||||
"constructor"
|
||||
).prefetch_related("switch_set__interface_set__domain")
|
||||
|
@ -323,7 +322,7 @@ def index_model_switch(request):
|
|||
@login_required
|
||||
@can_view_all(ModuleSwitch)
|
||||
def index_module(request):
|
||||
"""Display all modules of switchs"""
|
||||
"""View used to display all switch modules."""
|
||||
module_list = ModuleSwitch.objects.all()
|
||||
modular_switchs = (
|
||||
Switch.objects.filter(model__is_modular=True)
|
||||
|
@ -342,7 +341,7 @@ def index_module(request):
|
|||
@login_required
|
||||
@can_edit(Vlan)
|
||||
def edit_vlanoptions(request, vlan_instance, **_kwargs):
|
||||
""" View used to edit options for switch of VLAN object """
|
||||
"""View used to edit options for switch of VLAN object."""
|
||||
vlan = EditOptionVlanForm(request.POST or None, instance=vlan_instance)
|
||||
if vlan.is_valid():
|
||||
if vlan.changed_data:
|
||||
|
@ -357,7 +356,7 @@ def edit_vlanoptions(request, vlan_instance, **_kwargs):
|
|||
@login_required
|
||||
@can_create(Port)
|
||||
def new_port(request, switchid):
|
||||
""" Nouveau port"""
|
||||
"""View used to create ports."""
|
||||
try:
|
||||
switch = Switch.objects.get(pk=switchid)
|
||||
except Switch.DoesNotExist:
|
||||
|
@ -383,9 +382,10 @@ def new_port(request, switchid):
|
|||
@login_required
|
||||
@can_edit(Port)
|
||||
def edit_port(request, port_object, **_kwargs):
|
||||
""" Edition d'un port. Permet de changer le switch parent et
|
||||
l'affectation du port"""
|
||||
"""View used to edit ports.
|
||||
|
||||
It enables to change the related switch and the port assignment.
|
||||
"""
|
||||
port = EditPortForm(request.POST or None, instance=port_object)
|
||||
if port.is_valid():
|
||||
if port.changed_data:
|
||||
|
@ -410,7 +410,7 @@ def edit_port(request, port_object, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(Port)
|
||||
def del_port(request, port, **_kwargs):
|
||||
""" Supprime le port"""
|
||||
"""View used to delete ports."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
port.delete()
|
||||
|
@ -435,7 +435,7 @@ def del_port(request, port, **_kwargs):
|
|||
@login_required
|
||||
@can_create(Stack)
|
||||
def new_stack(request):
|
||||
"""Ajoute un nouveau stack : stackid_min, max, et nombre de switches"""
|
||||
"""View used to create stacks."""
|
||||
stack = StackForm(request.POST or None)
|
||||
if stack.is_valid():
|
||||
stack.save()
|
||||
|
@ -449,7 +449,7 @@ def new_stack(request):
|
|||
@login_required
|
||||
@can_edit(Stack)
|
||||
def edit_stack(request, stack, **_kwargs):
|
||||
"""Edition d'un stack (nombre de switches, nom...)"""
|
||||
"""View used to edit stacks."""
|
||||
stack = StackForm(request.POST or None, instance=stack)
|
||||
if stack.is_valid():
|
||||
if stack.changed_data:
|
||||
|
@ -464,7 +464,7 @@ def edit_stack(request, stack, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(Stack)
|
||||
def del_stack(request, stack, **_kwargs):
|
||||
"""Supprime un stack"""
|
||||
"""View used to delete stacks."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
stack.delete()
|
||||
|
@ -487,8 +487,7 @@ def del_stack(request, stack, **_kwargs):
|
|||
@login_required
|
||||
@can_edit(Stack)
|
||||
def edit_switchs_stack(request, stack, **_kwargs):
|
||||
"""Permet d'éditer la liste des switches dans une stack et l'ajouter"""
|
||||
|
||||
"""View used to edit the list of switches of the given stack."""
|
||||
if request.method == "POST":
|
||||
pass
|
||||
else:
|
||||
|
@ -500,9 +499,12 @@ def edit_switchs_stack(request, stack, **_kwargs):
|
|||
@login_required
|
||||
@can_create(Switch)
|
||||
def new_switch(request):
|
||||
""" Creation d'un switch. Cree en meme temps l'interface et la machine
|
||||
associée. Vue complexe. Appelle successivement les 4 models forms
|
||||
adaptés : machine, interface, domain et switch"""
|
||||
"""View used to create switches.
|
||||
|
||||
At the same time, it creates the related interface and machine. The view
|
||||
successively calls the 4 appropriate forms: machine, interface, domain and
|
||||
switch.
|
||||
"""
|
||||
switch = NewSwitchForm(request.POST or None, user=request.user)
|
||||
interface = AddInterfaceForm(request.POST or None, user=request.user)
|
||||
domain = DomainForm(request.POST or None, user=request.user)
|
||||
|
@ -549,7 +551,7 @@ def new_switch(request):
|
|||
@login_required
|
||||
@can_create(Port)
|
||||
def create_ports(request, switchid):
|
||||
""" Création d'une liste de ports pour un switch."""
|
||||
"""View used to create port lists for the given switch."""
|
||||
try:
|
||||
switch = Switch.objects.get(pk=switchid)
|
||||
except Switch.DoesNotExist:
|
||||
|
@ -578,9 +580,11 @@ def create_ports(request, switchid):
|
|||
@login_required
|
||||
@can_edit(Switch)
|
||||
def edit_switch(request, switch, switchid):
|
||||
""" Edition d'un switch. Permet de chambre nombre de ports,
|
||||
place dans le stack, interface et machine associée"""
|
||||
"""View used to edit switches.
|
||||
|
||||
It enables to change the number of ports, location in the stack, or the
|
||||
related interface and machine.
|
||||
"""
|
||||
switch_form = EditSwitchForm(
|
||||
request.POST or None, instance=switch, user=request.user
|
||||
)
|
||||
|
@ -622,9 +626,11 @@ def edit_switch(request, switch, switchid):
|
|||
@login_required
|
||||
@can_create(AccessPoint)
|
||||
def new_ap(request):
|
||||
""" Creation d'une ap. Cree en meme temps l'interface et la machine
|
||||
associée. Vue complexe. Appelle successivement les 3 models forms
|
||||
adaptés : machine, interface, domain et switch"""
|
||||
"""View used to create APs.
|
||||
|
||||
At the same time, it creates the related interface and machine. The view
|
||||
successively calls the 3 appropriate forms: machine, interface, domain.
|
||||
"""
|
||||
ap = AddAccessPointForm(request.POST or None, user=request.user)
|
||||
interface = AddInterfaceForm(request.POST or None, user=request.user)
|
||||
domain = DomainForm(request.POST or None, user=request.user)
|
||||
|
@ -671,8 +677,7 @@ def new_ap(request):
|
|||
@login_required
|
||||
@can_edit(AccessPoint)
|
||||
def edit_ap(request, ap, **_kwargs):
|
||||
""" Edition d'un switch. Permet de chambre nombre de ports,
|
||||
place dans le stack, interface et machine associée"""
|
||||
"""View used to edit APs."""
|
||||
interface_form = EditInterfaceForm(
|
||||
request.POST or None, user=request.user, instance=ap.interface_set.first()
|
||||
)
|
||||
|
@ -723,7 +728,7 @@ def edit_ap(request, ap, **_kwargs):
|
|||
@login_required
|
||||
@can_create(Room)
|
||||
def new_room(request):
|
||||
"""Nouvelle chambre """
|
||||
"""View used to create rooms."""
|
||||
room = EditRoomForm(request.POST or None)
|
||||
if room.is_valid():
|
||||
room.save()
|
||||
|
@ -737,7 +742,7 @@ def new_room(request):
|
|||
@login_required
|
||||
@can_edit(Room)
|
||||
def edit_room(request, room, **_kwargs):
|
||||
""" Edition numero et details de la chambre"""
|
||||
"""View used to edit rooms."""
|
||||
room = EditRoomForm(request.POST or None, instance=room)
|
||||
if room.is_valid():
|
||||
if room.changed_data:
|
||||
|
@ -752,7 +757,7 @@ def edit_room(request, room, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(Room)
|
||||
def del_room(request, room, **_kwargs):
|
||||
""" Suppression d'un chambre"""
|
||||
"""View used to delete rooms."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
room.delete()
|
||||
|
@ -777,7 +782,7 @@ def del_room(request, room, **_kwargs):
|
|||
@login_required
|
||||
@can_create(ModelSwitch)
|
||||
def new_model_switch(request):
|
||||
"""Nouveau modèle de switch"""
|
||||
"""View used to create switch models."""
|
||||
model_switch = EditModelSwitchForm(request.POST or None)
|
||||
if model_switch.is_valid():
|
||||
model_switch.save()
|
||||
|
@ -793,8 +798,7 @@ def new_model_switch(request):
|
|||
@login_required
|
||||
@can_edit(ModelSwitch)
|
||||
def edit_model_switch(request, model_switch, **_kwargs):
|
||||
""" Edition d'un modèle de switch"""
|
||||
|
||||
"""View used to edit switch models."""
|
||||
model_switch = EditModelSwitchForm(request.POST or None, instance=model_switch)
|
||||
if model_switch.is_valid():
|
||||
if model_switch.changed_data:
|
||||
|
@ -811,7 +815,7 @@ def edit_model_switch(request, model_switch, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(ModelSwitch)
|
||||
def del_model_switch(request, model_switch, **_kwargs):
|
||||
""" Suppression d'un modèle de switch"""
|
||||
"""View used to delete switch models."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
model_switch.delete()
|
||||
|
@ -838,7 +842,7 @@ def del_model_switch(request, model_switch, **_kwargs):
|
|||
@login_required
|
||||
@can_create(SwitchBay)
|
||||
def new_switch_bay(request):
|
||||
"""Nouvelle baie de switch"""
|
||||
"""View used to create switch bays."""
|
||||
switch_bay = EditSwitchBayForm(request.POST or None)
|
||||
if switch_bay.is_valid():
|
||||
switch_bay.save()
|
||||
|
@ -854,7 +858,7 @@ def new_switch_bay(request):
|
|||
@login_required
|
||||
@can_edit(SwitchBay)
|
||||
def edit_switch_bay(request, switch_bay, **_kwargs):
|
||||
""" Edition d'une baie de switch"""
|
||||
"""View used to edit switch bays."""
|
||||
switch_bay = EditSwitchBayForm(request.POST or None, instance=switch_bay)
|
||||
if switch_bay.is_valid():
|
||||
if switch_bay.changed_data:
|
||||
|
@ -871,7 +875,7 @@ def edit_switch_bay(request, switch_bay, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(SwitchBay)
|
||||
def del_switch_bay(request, switch_bay, **_kwargs):
|
||||
""" Suppression d'une baie de switch"""
|
||||
"""View used to delete switch bays."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
switch_bay.delete()
|
||||
|
@ -898,8 +902,7 @@ def del_switch_bay(request, switch_bay, **_kwargs):
|
|||
@login_required
|
||||
@can_create(Building)
|
||||
def new_building(request):
|
||||
"""New Building of a dorm
|
||||
Nouveau batiment"""
|
||||
"""View used to create buildings."""
|
||||
building = EditBuildingForm(request.POST or None)
|
||||
if building.is_valid():
|
||||
building.save()
|
||||
|
@ -915,8 +918,7 @@ def new_building(request):
|
|||
@login_required
|
||||
@can_edit(Building)
|
||||
def edit_building(request, building, **_kwargs):
|
||||
"""Edit a building
|
||||
Edition d'un batiment"""
|
||||
"""View used to edit buildings."""
|
||||
building = EditBuildingForm(request.POST or None, instance=building)
|
||||
if building.is_valid():
|
||||
if building.changed_data:
|
||||
|
@ -931,8 +933,7 @@ def edit_building(request, building, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(Building)
|
||||
def del_building(request, building, **_kwargs):
|
||||
"""Delete a building
|
||||
Suppression d'un batiment"""
|
||||
"""View used to delete buildings."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
building.delete()
|
||||
|
@ -959,8 +960,7 @@ def del_building(request, building, **_kwargs):
|
|||
@login_required
|
||||
@can_create(Dormitory)
|
||||
def new_dormitory(request):
|
||||
"""A new dormitory
|
||||
Nouvelle residence"""
|
||||
"""View used to create dormitories."""
|
||||
dormitory = EditDormitoryForm(request.POST or None)
|
||||
if dormitory.is_valid():
|
||||
dormitory.save()
|
||||
|
@ -976,8 +976,7 @@ def new_dormitory(request):
|
|||
@login_required
|
||||
@can_edit(Dormitory)
|
||||
def edit_dormitory(request, dormitory, **_kwargs):
|
||||
"""Edit a dormitory
|
||||
Edition d'une residence"""
|
||||
"""View used to edit dormitories."""
|
||||
dormitory = EditDormitoryForm(request.POST or None, instance=dormitory)
|
||||
if dormitory.is_valid():
|
||||
if dormitory.changed_data:
|
||||
|
@ -994,8 +993,7 @@ def edit_dormitory(request, dormitory, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(Dormitory)
|
||||
def del_dormitory(request, dormitory, **_kwargs):
|
||||
"""Delete a dormitory
|
||||
Suppression d'une residence"""
|
||||
"""View used to delete dormitories."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
dormitory.delete()
|
||||
|
@ -1022,7 +1020,7 @@ def del_dormitory(request, dormitory, **_kwargs):
|
|||
@login_required
|
||||
@can_create(ConstructorSwitch)
|
||||
def new_constructor_switch(request):
|
||||
"""Nouveau constructeur de switch"""
|
||||
"""View used to create switch constructors."""
|
||||
constructor_switch = EditConstructorSwitchForm(request.POST or None)
|
||||
if constructor_switch.is_valid():
|
||||
constructor_switch.save()
|
||||
|
@ -1038,8 +1036,7 @@ def new_constructor_switch(request):
|
|||
@login_required
|
||||
@can_edit(ConstructorSwitch)
|
||||
def edit_constructor_switch(request, constructor_switch, **_kwargs):
|
||||
""" Edition d'un constructeur de switch"""
|
||||
|
||||
"""View used to edit switch constructors."""
|
||||
constructor_switch = EditConstructorSwitchForm(
|
||||
request.POST or None, instance=constructor_switch
|
||||
)
|
||||
|
@ -1058,7 +1055,7 @@ def edit_constructor_switch(request, constructor_switch, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(ConstructorSwitch)
|
||||
def del_constructor_switch(request, constructor_switch, **_kwargs):
|
||||
""" Suppression d'un constructeur de switch"""
|
||||
"""View used to delete switch constructors."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
constructor_switch.delete()
|
||||
|
@ -1085,7 +1082,7 @@ def del_constructor_switch(request, constructor_switch, **_kwargs):
|
|||
@login_required
|
||||
@can_create(PortProfile)
|
||||
def new_port_profile(request):
|
||||
"""Create a new port profile"""
|
||||
"""View used to create port profiles."""
|
||||
port_profile = EditPortProfileForm(request.POST or None)
|
||||
if port_profile.is_valid():
|
||||
port_profile.save()
|
||||
|
@ -1101,7 +1098,7 @@ def new_port_profile(request):
|
|||
@login_required
|
||||
@can_edit(PortProfile)
|
||||
def edit_port_profile(request, port_profile, **_kwargs):
|
||||
"""Edit a port profile"""
|
||||
"""View used to edit port profiles."""
|
||||
port_profile = EditPortProfileForm(request.POST or None, instance=port_profile)
|
||||
if port_profile.is_valid():
|
||||
if port_profile.changed_data:
|
||||
|
@ -1118,7 +1115,7 @@ def edit_port_profile(request, port_profile, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(PortProfile)
|
||||
def del_port_profile(request, port_profile, **_kwargs):
|
||||
"""Delete a port profile"""
|
||||
"""View used to delete port profiles."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
port_profile.delete()
|
||||
|
@ -1136,7 +1133,7 @@ def del_port_profile(request, port_profile, **_kwargs):
|
|||
@login_required
|
||||
@can_create(ModuleSwitch)
|
||||
def add_module(request):
|
||||
""" View used to add a Module object """
|
||||
"""View used to create switch modules."""
|
||||
module = EditModuleForm(request.POST or None)
|
||||
if module.is_valid():
|
||||
module.save()
|
||||
|
@ -1150,7 +1147,7 @@ def add_module(request):
|
|||
@login_required
|
||||
@can_edit(ModuleSwitch)
|
||||
def edit_module(request, module_instance, **_kwargs):
|
||||
""" View used to edit a Module object """
|
||||
"""View used to edit switch modules."""
|
||||
module = EditModuleForm(request.POST or None, instance=module_instance)
|
||||
if module.is_valid():
|
||||
if module.changed_data:
|
||||
|
@ -1165,7 +1162,7 @@ def edit_module(request, module_instance, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(ModuleSwitch)
|
||||
def del_module(request, module, **_kwargs):
|
||||
"""Compleete delete a module"""
|
||||
"""View used to delete switch modules."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
module.delete()
|
||||
|
@ -1190,7 +1187,7 @@ def del_module(request, module, **_kwargs):
|
|||
@login_required
|
||||
@can_create(ModuleOnSwitch)
|
||||
def add_module_on(request):
|
||||
"""Add a module to a switch"""
|
||||
"""View used to add a module to a switch."""
|
||||
module_switch = EditSwitchModuleForm(request.POST or None)
|
||||
if module_switch.is_valid():
|
||||
module_switch.save()
|
||||
|
@ -1206,7 +1203,7 @@ def add_module_on(request):
|
|||
@login_required
|
||||
@can_edit(ModuleOnSwitch)
|
||||
def edit_module_on(request, module_instance, **_kwargs):
|
||||
""" View used to edit a Module object """
|
||||
"""View used to edit a module on a switch."""
|
||||
module = EditSwitchModuleForm(request.POST or None, instance=module_instance)
|
||||
if module.is_valid():
|
||||
if module.changed_data:
|
||||
|
@ -1221,7 +1218,7 @@ def edit_module_on(request, module_instance, **_kwargs):
|
|||
@login_required
|
||||
@can_delete(ModuleOnSwitch)
|
||||
def del_module_on(request, module, **_kwargs):
|
||||
"""Compleete delete a module"""
|
||||
"""View used to delete a module on a switch."""
|
||||
if request.method == "POST":
|
||||
try:
|
||||
module.delete()
|
||||
|
@ -1244,9 +1241,7 @@ def del_module_on(request, module, **_kwargs):
|
|||
|
||||
|
||||
def make_machine_graph():
|
||||
"""
|
||||
Create the graph of switchs, machines and access points.
|
||||
"""
|
||||
"""Create the graph of switches, machines and access points."""
|
||||
dico = {
|
||||
"subs": [],
|
||||
"links": [],
|
||||
|
@ -1284,7 +1279,7 @@ def make_machine_graph():
|
|||
"machines": [],
|
||||
}
|
||||
)
|
||||
# Visit all switchs in this building
|
||||
# Visit all switches in this building
|
||||
for switch in (
|
||||
Switch.objects.filter(switchbay__building=building)
|
||||
.prefetch_related(
|
||||
|
@ -1311,7 +1306,7 @@ def make_machine_graph():
|
|||
"ports": [],
|
||||
}
|
||||
)
|
||||
# visit all ports of this switch and add the switchs linked to it
|
||||
# visit all ports of this switch and add the switches linked to it
|
||||
for port in switch.ports.filter(related__isnull=False).select_related(
|
||||
"related__switch"
|
||||
):
|
||||
|
@ -1365,29 +1360,29 @@ def make_machine_graph():
|
|||
links, new_detected = recursive_switchs(missing[0], None, [missing[0]])
|
||||
for link in links:
|
||||
dico["links"].append(link)
|
||||
# Update the lists of missings and already detected switchs
|
||||
# Update the lists of missings and already detected switches
|
||||
missing = [i for i in missing if i not in new_detected]
|
||||
detected += new_detected
|
||||
# If the switch have no ports, don't explore it and hop to the next one
|
||||
# If the switch has no ports, don't explore it and hop to the next one
|
||||
else:
|
||||
del missing[0]
|
||||
# Switchs that are not connected or not in a building
|
||||
# Switches that are not connected or not in a building
|
||||
for switch in Switch.objects.filter(switchbay__isnull=True).exclude(
|
||||
ports__related__isnull=False
|
||||
):
|
||||
dico["alone"].append({"id": switch.id, "name": switch.get_name})
|
||||
|
||||
# generate the dot file
|
||||
# Generate the dot file
|
||||
dot_data = generate_dot(dico, "topologie/graph_switch.dot")
|
||||
|
||||
# Create a temporary file to store the dot data
|
||||
f = tempfile.NamedTemporaryFile(mode="w+", encoding="utf-8", delete=False)
|
||||
with f:
|
||||
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], stdout=PIPE
|
||||
)
|
||||
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"],
|
||||
stdin=unflatten.stdout,
|
||||
stdout=PIPE,
|
||||
|
@ -1395,10 +1390,15 @@ def make_machine_graph():
|
|||
|
||||
|
||||
def generate_dot(data, template):
|
||||
"""create the dot file
|
||||
:param data: dictionary passed to the template
|
||||
:param template: path to the dot template
|
||||
:return: all the lines of the dot file"""
|
||||
"""Generate a dot file from the data and template given.
|
||||
|
||||
Args:
|
||||
data: dictionary passed to the template.
|
||||
template: path to the dot template.
|
||||
|
||||
Returns:
|
||||
All the lines of the dot file.
|
||||
"""
|
||||
t = loader.get_template(template)
|
||||
if not isinstance(t, Template) and not (
|
||||
hasattr(t, "template") and isinstance(t.template, Template)
|
||||
|
@ -1415,18 +1415,19 @@ def generate_dot(data, template):
|
|||
|
||||
|
||||
def recursive_switchs(switch_start, switch_before, detected):
|
||||
"""Visit the switch and travel to the switchs linked to it.
|
||||
: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 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
|
||||
"""Visit the switch and travel to the switches linked to it.
|
||||
|
||||
Args:
|
||||
switch_start: the switch to begin the visit on.
|
||||
switch_before: the switch that you come from. None if switch_start is the first one.
|
||||
detected: list of all switches already visited. None if switch_start is the first one.
|
||||
|
||||
Returns:
|
||||
A list of all the links found and a list of all the switches visited.
|
||||
"""
|
||||
detected.append(switch_start)
|
||||
links_return = [] # list of dictionaries of the links to be detected
|
||||
# create links to every switchs below
|
||||
links_return = [] # List of dictionaries of the links to be detected
|
||||
# Create links to every switches below
|
||||
for port in switch_start.ports.filter(related__isnull=False):
|
||||
# Not the switch that we come from, not the current switch
|
||||
if (
|
||||
|
@ -1440,11 +1441,11 @@ def recursive_switchs(switch_start, switch_before, detected):
|
|||
}
|
||||
links_return.append(links) # Add current and below levels links
|
||||
|
||||
# go down on every related switchs
|
||||
# Go down on every related switches
|
||||
for port in switch_start.ports.filter(related__isnull=False):
|
||||
# The switch at the end of this link has not been visited
|
||||
if port.related.switch not in detected:
|
||||
# explore it and get the results
|
||||
# Explore it and get the results
|
||||
links_down, detected = recursive_switchs(
|
||||
port.related.switch, switch_start, detected
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue