diff --git a/topologie/models.py b/topologie/models.py index 7ac10243..c02c0c51 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -34,17 +34,11 @@ import reversion from machines.models import Vlan -def make_port_related(port): - related_port = port.related - related_port.related = port - related_port.save() - -def clean_port_related(port): - related_port = port.related_port - related_port.related = None - related_port.save() class Stack(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""" PRETTY_NAME = "Stack de switchs" name = models.CharField(max_length=32, blank=True, null=True) @@ -57,15 +51,25 @@ class Stack(models.Model): return " ".join([self.name, self.stack_id]) def save(self, *args, **kwargs): + self.clean() if not self.name: self.name = self.stack_id super(Stack, self).save(*args, **kwargs) def clean(self): + """ Verification que l'id_max < id_min""" if self.member_id_max < self.member_id_min: raise ValidationError({'member_id_max':"L'id maximale est inférieure à l'id minimale"}) class Switch(models.Model): + """ 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""" PRETTY_NAME = "Switch / Commutateur" switch_interface = models.OneToOneField('machines.Interface', on_delete=models.CASCADE) @@ -82,6 +86,7 @@ class Switch(models.Model): return str(self.location) + ' ' + str(self.switch_interface) def clean(self): + """ Verifie que l'id stack est dans le bon range""" if self.stack is not None: if self.stack_member_id is not None: if (self.stack_member_id > self.stack.member_id_max) or (self.stack_member_id < self.stack.member_id_min): @@ -90,6 +95,20 @@ class Switch(models.Model): raise ValidationError({'stack_member_id': "L'id dans la stack ne peut être nul"}) class Port(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""" PRETTY_NAME = "Port de switch" STATES = ( ('NO', 'NO'), @@ -110,7 +129,26 @@ class Port(models.Model): class Meta: unique_together = ('switch', 'port') + def make_port_related(self): + """ Synchronise le port distant sur self""" + related_port = self.related + related_port.related = self + related_port.save() + + def clean_port_related(self): + """ Supprime la relation related sur 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""" if hasattr(self, 'switch'): if self.port > self.switch.number: raise ValidationError("Ce port ne peut exister, numero trop élevé") @@ -122,14 +160,15 @@ class Port(models.Model): if self.related.machine_interface or self.related.room: raise ValidationError("Le port relié est déjà occupé, veuillez le libérer avant de créer une relation") else: - make_port_related(self) + self.make_port_related() elif hasattr(self, 'related_port'): - clean_port_related(self) + self.clean_port_related() def __str__(self): return str(self.switch) + " - " + str(self.port) class Room(models.Model): + """ Une chambre/local contenant une prise murale""" PRETTY_NAME = "Chambre/ Prise murale" name = models.CharField(max_length=255, unique=True) diff --git a/topologie/views.py b/topologie/views.py index 4e453d7c..eba00e0c 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -44,12 +44,14 @@ from preferences.models import AssoOption, GeneralOption @login_required @permission_required('cableur') def index(request): + """ Vue d'affichage de tous les swicthes""" switch_list = Switch.objects.order_by('stack','stack_member_id','location').select_related('switch_interface__domain__extension').select_related('switch_interface__ipv4').select_related('switch_interface__domain') return render(request, 'topologie/index.html', {'switch_list': switch_list}) @login_required @permission_required('cableur') def history(request, object, id): + """ Vue générique pour afficher l'historique complet d'un objet""" if object == 'switch': try: object_instance = Switch.objects.get(pk=id) @@ -95,6 +97,7 @@ def history(request, object, id): @login_required @permission_required('cableur') def index_port(request, switch_id): + """ Affichage de l'ensemble des ports reliés à un switch particulier""" try: switch = Switch.objects.get(pk=switch_id) except Switch.DoesNotExist: @@ -106,6 +109,7 @@ def index_port(request, switch_id): @login_required @permission_required('cableur') def index_room(request): + """ Affichage de l'ensemble des chambres""" room_list = Room.objects.order_by('name') options, created = GeneralOption.objects.get_or_create() pagination_number = options.pagination_number @@ -131,6 +135,7 @@ def index_stack(request): @login_required @permission_required('infra') def new_port(request, switch_id): + """ Nouveau port""" try: switch = Switch.objects.get(pk=switch_id) except Switch.DoesNotExist: @@ -154,6 +159,7 @@ def new_port(request, switch_id): @login_required @permission_required('infra') def edit_port(request, port_id): + """ Edition d'un port. Permet de changer le switch parent et l'affectation du port""" try: port_object = Port.objects.select_related('switch__switch_interface__domain__extension').select_related('machine_interface__domain__extension').select_related('machine_interface__switch').select_related('room').select_related('related').get(pk=port_id) except Port.DoesNotExist: @@ -172,6 +178,7 @@ def edit_port(request, port_id): @login_required @permission_required('infra') def del_port(request,port_id): + """ Supprime le port""" try: port = Port.objects.get(pk=port_id) except Port.DoesNotExist: @@ -263,6 +270,9 @@ def edit_switchs_stack(request,stack_id): @login_required @permission_required('infra') 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""" switch = NewSwitchForm(request.POST or None) machine = NewMachineForm(request.POST or None) interface = AddInterfaceForm(request.POST or None, infra=request.user.has_perms(('infra',))) @@ -304,6 +314,8 @@ def new_switch(request): @login_required @permission_required('infra') def edit_switch(request, switch_id): + """ Edition d'un switch. Permet de chambre nombre de ports, place dans le stack, + interface et machine associée""" try: switch = Switch.objects.get(pk=switch_id) except Switch.DoesNotExist: @@ -341,6 +353,7 @@ def edit_switch(request, switch_id): @login_required @permission_required('infra') def new_room(request): + """Nouvelle chambre """ room = EditRoomForm(request.POST or None) if room.is_valid(): with transaction.atomic(), reversion.create_revision(): @@ -354,6 +367,7 @@ def new_room(request): @login_required @permission_required('infra') def edit_room(request, room_id): + """ Edition numero et details de la chambre""" try: room = Room.objects.get(pk=room_id) except Room.DoesNotExist: @@ -372,6 +386,7 @@ def edit_room(request, room_id): @login_required @permission_required('infra') def del_room(request, room_id): + """ Suppression d'un chambre""" try: room = Room.objects.get(pk=room_id) except Room.DoesNotExist: