Commit d5d4e219 authored by Gabriel Detraz's avatar Gabriel Detraz Committed by root

Deplace les checks dans les models + liaison entre ip_type et ip_list ranges

parent bbe687c2
......@@ -74,7 +74,7 @@ class AddInterfaceForm(EditInterfaceForm):
self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4"
if not infra:
self.fields['type'].queryset = MachineType.objects.filter(ip_type__in=IpType.objects.filter(need_infra=False))
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False)).filter(need_infra=False)
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False))
else:
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True)
......@@ -92,7 +92,7 @@ class BaseEditInterfaceForm(EditInterfaceForm):
self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4"
if not infra:
self.fields['type'].queryset = MachineType.objects.filter(ip_type__in=IpType.objects.filter(need_infra=False))
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False)).filter(need_infra=False)
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False))
else:
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True)
......@@ -152,13 +152,12 @@ class IpTypeForm(ModelForm):
super(IpTypeForm, self).__init__(*args, **kwargs)
self.fields['type'].label = 'Type ip à ajouter'
class DelIpTypeForm(ModelForm):
iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple)
class Meta:
exclude = ['type','extension','need_infra','domaine_ip','domaine_range']
model = IpType
class EditIpTypeForm(IpTypeForm):
class Meta(IpTypeForm.Meta):
fields = ['extension','type','need_infra']
class DelIpTypeForm(forms.Form):
iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple)
class ExtensionForm(ModelForm):
class Meta:
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-07-21 01:50
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('machines', '0042_ns_ns'),
]
operations = [
migrations.RemoveField(
model_name='iplist',
name='need_infra',
),
migrations.AlterField(
model_name='iplist',
name='ip_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.IpType'),
),
]
......@@ -21,13 +21,14 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from django.db import models
from django.db.models.signals import post_save, post_delete
from django.db.models.signals import post_save, pre_delete, post_delete
from django.dispatch import receiver
from django.forms import ValidationError
from django.utils.functional import cached_property
from macaddress.fields import MACAddressField
from netaddr import mac_bare, EUI
from netaddr import mac_bare, EUI, IPSet, IPNetwork
from django.core.validators import MinValueValidator,MaxValueValidator
from django.utils.functional import cached_property
import re
from re2o.settings import MAIN_EXTENSION
......@@ -59,6 +60,48 @@ class IpType(models.Model):
domaine_ip = models.GenericIPAddressField(protocol='IPv4')
domaine_range = models.IntegerField(validators=[MinValueValidator(8), MaxValueValidator(32)])
@cached_property
def network(self):
return str(self.domaine_ip) + '/' + str(self.domaine_range)
@cached_property
def ip_network(self):
return IPNetwork(self.network)
@cached_property
def ip_set(self):
return IPSet(self.ip_network)
@cached_property
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)
def gen_ip_range(self):
# Creation du range d'ip dans les objets iplist
for ip in self.ip_network.iter_hosts():
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):
raise ValidationError("Une ou plusieurs ip du range sont affectées, impossible de supprimer le range")
for ip in self.ip_objects():
ip.delete()
def clean(self):
# On check que les / ne se recoupent pas
for element in IpType.objects.all():
if not self.ip_set.isdisjoint(element.ip_set):
raise ValidationError("Le range indiqué n'est pas disjoint des ranges existants")
return
def save(self, *args, **kwargs):
self.clean()
super(IpType, self).save(*args, **kwargs)
def __str__(self):
return self.type
......@@ -133,10 +176,18 @@ class Domain(models.Model):
unique_together = ("name", "extension")
def clean(self):
""" Validation du nom de domaine, extensions dans type de machine, prefixe pas plus long que 63 caractères """
if self.interface_parent and self.cname:
raise ValidationError("On ne peut créer à la fois A et CNAME")
if self.cname==self:
raise ValidationError("On ne peut créer un cname sur lui même")
HOSTNAME_LABEL_PATTERN = re.compile("(?!-)[A-Z\d-]+(?<!-)$", re.IGNORECASE)
dns = self.name.lower()
if len(dns) > 63:
raise ValidationError("Le nom de domaine %s est trop long (maximum de 63 caractères)." % dns)
if not HOSTNAME_LABEL_PATTERN.match(dns):
raise ValidationError("Ce nom de domaine %s contient des carractères interdits." % dns)
return
def __str__(self):
return str(self.name) + str(self.extension)
......@@ -145,8 +196,20 @@ class IpList(models.Model):
PRETTY_NAME = "Addresses ipv4"
ipv4 = models.GenericIPAddressField(protocol='IPv4', unique=True)
ip_type = models.ForeignKey('IpType', on_delete=models.PROTECT)
need_infra = models.BooleanField(default=False)
ip_type = models.ForeignKey('IpType', on_delete=models.CASCADE)
@cached_property
def need_infra(self):
return self.ip_type.need_infra
def clean(self):
if not str(self.ipv4) in self.ip_type.ip_set_as_str:
raise ValidationError("L'ipv4 et le range de l'iptype ne correspondent pas!")
return
def save(self, *args, **kwargs):
self.clean()
super(IpList, self).save(*args, **kwargs)
def __str__(self):
return self.ipv4
......@@ -173,3 +236,8 @@ def interface_post_delete(sender, **kwargs):
user = interface.machine.user
user.ldap_sync(base=False, access_refresh=False, mac_refresh=True)
@receiver(post_save, sender=IpType)
def iptype_post_save(sender, **kwargs):
iptype = kwargs['instance']
iptype.gen_ip_range()
This diff is collapsed.
......@@ -35,7 +35,7 @@ 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, full_domain_validator, assign_ipv4
from machines.views import free_ip, assign_ipv4
from preferences.models import GeneralOption
from re2o.settings import ASSO_PSEUDO
......@@ -161,32 +161,31 @@ def new_switch(request):
new_interface = interface.save(commit=False)
new_switch = switch.save(commit=False)
new_domain = domain.save(commit=False)
if full_domain_validator(request, new_domain):
with transaction.atomic(), reversion.create_revision():
new_machine.save()
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)
reversion.set_comment("Création")
new_domain.interface_parent = new_interface
with transaction.atomic(), reversion.create_revision():
new_domain.save()
reversion.set_user(request.user)
reversion.set_comment("Création")
new_switch.switch_interface = new_interface
with transaction.atomic(), reversion.create_revision():
new_switch.save()
reversion.set_user(request.user)
reversion.set_comment("Création")
messages.success(request, "Le switch a été crée")
return redirect("/topologie/")
with transaction.atomic(), reversion.create_revision():
new_machine.save()
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)
reversion.set_comment("Création")
new_domain.interface_parent = new_interface
with transaction.atomic(), reversion.create_revision():
new_domain.save()
reversion.set_user(request.user)
reversion.set_comment("Création")
new_switch.switch_interface = new_interface
with transaction.atomic(), reversion.create_revision():
new_switch.save()
reversion.set_user(request.user)
reversion.set_comment("Création")
messages.success(request, "Le switch a été crée")
return redirect("/topologie/")
return form({'topoform':switch, 'machineform': machine, 'interfaceform': interface, 'domainform': domain}, 'topologie/switch.html', request)
@login_required
......@@ -206,25 +205,24 @@ def edit_switch(request, switch_id):
new_machine = machine_form.save(commit=False)
new_switch = switch_form.save(commit=False)
new_domain = domain_form.save(commit=False)
if full_domain_validator(request, new_domain):
with transaction.atomic(), reversion.create_revision():
new_machine.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machine_form.changed_data))
with transaction.atomic(), reversion.create_revision():
new_interface.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in interface_form.changed_data))
with transaction.atomic(), reversion.create_revision():
new_domain.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in domain_form.changed_data))
with transaction.atomic(), reversion.create_revision():
new_switch.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in switch_form.changed_data))
messages.success(request, "Le switch a bien été modifié")
return redirect("/topologie/")
with transaction.atomic(), reversion.create_revision():
new_machine.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machine_form.changed_data))
with transaction.atomic(), reversion.create_revision():
new_interface.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in interface_form.changed_data))
with transaction.atomic(), reversion.create_revision():
new_domain.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in domain_form.changed_data))
with transaction.atomic(), reversion.create_revision():
new_switch.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in switch_form.changed_data))
messages.success(request, "Le switch a bien été modifié")
return redirect("/topologie/")
return form({'topoform':switch_form, 'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form}, 'topologie/switch.html', request)
@login_required
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment