diff --git a/machines/models.py b/machines/models.py index a424b788..3181b9d6 100644 --- a/machines/models.py +++ b/machines/models.py @@ -29,6 +29,7 @@ from macaddress.fields import MACAddressField from netaddr import mac_bare, EUI, IPSet, IPNetwork from django.core.validators import MinValueValidator,MaxValueValidator import re +from reversion import revisions as reversion from re2o.settings import MAIN_EXTENSION @@ -76,9 +77,11 @@ class IpType(models.Model): def ip_set_as_str(self): return [str(x) for x in self.ip_set] - @cached_property def ip_objects(self): - return IpList.objects.filter(ipv4__in=self.ip_set_as_str) + return IpList.objects.filter(ip_type=self) + + def free_ip(self): + return IpList.objects.filter(interface__isnull=True).filter(ip_type=self) def gen_ip_range(self): # Creation du range d'ip dans les objets iplist @@ -86,7 +89,7 @@ class IpType(models.Model): obj, created = IpList.objects.get_or_create(ip_type=self, ipv4=str(ip)) def del_ip_range(self): - if Interface.objects.filter(ipv4__in=self.ip_objects): + if Interface.objects.filter(ipv4__in=self.ip_objects()): raise ValidationError("Une ou plusieurs ip du range sont affectées, impossible de supprimer le range") for ip in self.ip_objects(): ip.delete() @@ -156,6 +159,20 @@ class Interface(models.Model): def clean(self, *args, **kwargs): self.mac_address = str(EUI(self.mac_address)) or None + if not self.ipv4: + self.assign_ipv4() + + def assign_ipv4(self): + """ Assigne une ip à l'interface """ + free_ips = self.type.ip_type.free_ip() + if free_ips: + self.ipv4 = free_ips[0] + else: + raise ValidationError("Il n'y a plus d'ip disponibles dans le slash") + return + + def unassign_ipv4(self): + self.ipv4 = None def __str__(self): try: @@ -227,7 +244,8 @@ def machine_post_delete(sender, **kwargs): @receiver(post_save, sender=Interface) def interface_post_save(sender, **kwargs): - user = kwargs['instance'].machine.user + interface = kwargs['instance'] + user = interface.machine.user user.ldap_sync(base=False, access_refresh=False, mac_refresh=True) @receiver(post_delete, sender=Interface) diff --git a/machines/views.py b/machines/views.py index 3742deaf..c1c6a5df 100644 --- a/machines/views.py +++ b/machines/views.py @@ -66,40 +66,6 @@ def all_active_assigned_interfaces_count(): """ Version light seulement pour compter""" return all_active_interfaces_count().filter(ipv4__isnull=False) -def unassign_ips(user): - machines = user.user_interfaces() - for machine in machines: - unassign_ipv4(machine) - return - -def assign_ips(user): - """ Assign une ipv4 aux machines d'un user """ - machines = user.user_interfaces() - for machine in machines: - if not machine.ipv4: - interface = assign_ipv4(machine) - with transaction.atomic(), reversion.create_revision(): - reversion.set_comment("Assignation ipv4") - interface.save() - return - -def free_ip(type): - """ Renvoie la liste des ip disponibles """ - return IpList.objects.filter(interface__isnull=True).filter(ip_type=type) - -def assign_ipv4(interface): - """ Assigne une ip à l'interface """ - free_ips = free_ip(interface.type.ip_type) - if free_ips: - interface.ipv4 = free_ips[0] - return interface - -def unassign_ipv4(interface): - interface.ipv4 = None - with transaction.atomic(), reversion.create_revision(): - reversion.set_comment("Désassignation ipv4") - interface.save() - def form(ctx, template, request): c = ctx c.update(csrf(request)) @@ -136,10 +102,6 @@ def new_machine(request, userid): reversion.set_user(request.user) reversion.set_comment("Création") new_interface.machine = new_machine - if free_ip(new_interface.type.ip_type) and not new_interface.ipv4: - new_interface = assign_ipv4(new_interface) - elif not new_interface.ipv4: - messages.error(request, u"Il n'y a plus d'ip disponibles") with transaction.atomic(), reversion.create_revision(): new_interface.save() reversion.set_user(request.user) @@ -181,8 +143,6 @@ def edit_interface(request, interfaceid): new_machine.save() reversion.set_user(request.user) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machine_form.changed_data)) - if free_ip(new_interface.type.ip_type) and not new_interface.ipv4: - new_interface = assign_ipv4(new_interface) with transaction.atomic(), reversion.create_revision(): new_interface.save() reversion.set_user(request.user) @@ -239,10 +199,6 @@ def new_interface(request, machineid): new_interface = interface_form.save(commit=False) new_interface.machine = machine new_domain = domain_form.save(commit=False) - if free_ip(new_interface.type.ip_type) and not new_interface.ipv4: - new_interface = assign_ipv4(new_interface) - elif not new_interface.ipv4: - messages.error(request, u"Il n'y a plus d'ip disponibles") with transaction.atomic(), reversion.create_revision(): new_interface.save() reversion.set_user(request.user) diff --git a/topologie/views.py b/topologie/views.py index 8e8eaa48..4602845f 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -35,7 +35,6 @@ from users.views import form from users.models import User from machines.forms import AliasForm, NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm -from machines.views import free_ip, assign_ipv4 from preferences.models import GeneralOption from re2o.settings import ASSO_PSEUDO @@ -166,10 +165,6 @@ def new_switch(request): reversion.set_user(request.user) reversion.set_comment("Création") new_interface.machine = new_machine - if free_ip(new_interface.type.ip_type) and not new_interface.ipv4: - new_interface = assign_ipv4(new_interface) - elif not new_interface.ipv4: - messages.error(request, "Il n'y a plus d'ip disponibles") with transaction.atomic(), reversion.create_revision(): new_interface.save() reversion.set_user(request.user) diff --git a/users/models.py b/users/models.py index 544de914..472e02ba 100644 --- a/users/models.py +++ b/users/models.py @@ -27,6 +27,9 @@ from django.db.models.signals import post_save, post_delete from django.dispatch import receiver from django.utils.functional import cached_property +from reversion import revisions as reversion +from django.db import transaction + import ldapdb.models import ldapdb.models.fields @@ -327,6 +330,32 @@ class User(AbstractBaseUser): def user_interfaces(self): return Interface.objects.filter(machine__in=Machine.objects.filter(user=self, active=True)) + def assign_ips(self): + """ Assign une ipv4 aux machines d'un user """ + interfaces = self.user_interfaces() + for interface in interfaces: + if not interface.ipv4: + with transaction.atomic(), reversion.create_revision(): + interface.assign_ipv4() + reversion.set_comment("Assignation ipv4") + interface.save() + + def unassign_ips(self): + interfaces = self.user_interfaces() + for interface in interfaces: + with transaction.atomic(), reversion.create_revision(): + interface.unassign_ipv4() + reversion.set_comment("Désassignation ipv4") + interface.save() + + def archive(self): + self.unassign_ips() + self.state = User.STATE_ARCHIVE + + def unarchive(self): + self.assign_ips() + self.state = User.STATE_ACTIVE + def has_module_perms(self, app_label): # Simplest version again return True diff --git a/users/views.py b/users/views.py index 0a4fc3fb..2d9d716c 100644 --- a/users/views.py +++ b/users/views.py @@ -44,22 +44,11 @@ from users.forms import EditInfoForm, InfoForm, BaseInfoForm, StateForm, RightFo from cotisations.models import Facture from machines.models import Machine, Interface from users.forms import MassArchiveForm, PassForm, ResetPasswordForm -from machines.views import unassign_ips, assign_ips from preferences.models import OptionalUser, GeneralOption from re2o.login import hashNT from re2o.settings import REQ_EXPIRE_STR, EMAIL_FROM, ASSO_NAME, ASSO_EMAIL, SITE_NAME -def archive(user): - """ Archive un utilisateur """ - unassign_ips(user) - return - - -def unarchive(user): - """ Triger actions au desarchivage d'un user """ - assign_ips(user) - return def form(ctx, template, request): c = ctx @@ -180,15 +169,16 @@ def state(request, userid): return redirect("/users/") state = StateForm(request.POST or None, instance=user) if state.is_valid(): - if state.has_changed(): - if state.cleaned_data['state'] == User.STATE_ARCHIVE: - archive(user) - else: - unarchive(user) with transaction.atomic(), reversion.create_revision(): - state.save() + if state.cleaned_data['state'] == User.STATE_ARCHIVE: + user.archive() + elif state.cleaned_data['state'] == User.STATE_ACTIVE: + user.unarchive() + elif state.cleaned_data['state'] == User.STATE_DISABLED: + user.state = User.STATE_DISABLED reversion.set_user(request.user) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in state.changed_data)) + user.save() messages.success(request, "Etat changé avec succès") return redirect("/users/profil/" + userid) return form({'userform': state}, 'users/user.html', request) @@ -525,9 +515,8 @@ def mass_archive(request): to_archive_list = [user for user in User.objects.exclude(state=User.STATE_ARCHIVE) if not user.end_access or user.end_access < date] if "valider" in request.POST: for user in to_archive_list: - archive(user) with transaction.atomic(), reversion.create_revision(): - user.state=User.STATE_ARCHIVE + user.archive() user.save() reversion.set_user(request.user) reversion.set_comment("Archivage")