mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
Deplace les checks dans les models + liaison entre ip_type et ip_list ranges
This commit is contained in:
parent
bbe687c29b
commit
d5d4e2192b
5 changed files with 204 additions and 134 deletions
|
@ -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,14 +152,13 @@ class IpTypeForm(ModelForm):
|
|||
super(IpTypeForm, self).__init__(*args, **kwargs)
|
||||
self.fields['type'].label = 'Type ip à ajouter'
|
||||
|
||||
class DelIpTypeForm(ModelForm):
|
||||
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 Meta:
|
||||
exclude = ['type','extension','need_infra','domaine_ip','domaine_range']
|
||||
model = IpType
|
||||
|
||||
|
||||
class ExtensionForm(ModelForm):
|
||||
class Meta:
|
||||
model = Extension
|
||||
|
|
25
machines/migrations/0043_auto_20170721_0350.py
Normal file
25
machines/migrations/0043_auto_20170721_0350.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- 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 macaddress.fields import MACAddressField
|
||||
from netaddr import mac_bare, EUI
|
||||
from django.core.validators import MinValueValidator,MaxValueValidator
|
||||
from django.utils.functional import cached_property
|
||||
from macaddress.fields import MACAddressField
|
||||
from netaddr import mac_bare, EUI, IPSet, IPNetwork
|
||||
from django.core.validators import MinValueValidator,MaxValueValidator
|
||||
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()
|
||||
|
||||
|
|
|
@ -44,26 +44,12 @@ from reversion.models import Version
|
|||
|
||||
import re
|
||||
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm
|
||||
from .forms import IpTypeForm, DelIpTypeForm, AliasForm, DelAliasForm, NsForm, DelNsForm, MxForm, DelMxForm
|
||||
from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, AliasForm, DelAliasForm, NsForm, DelNsForm, MxForm, DelMxForm
|
||||
from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain
|
||||
from users.models import User
|
||||
from users.models import all_has_access
|
||||
from preferences.models import GeneralOption, OptionalMachine
|
||||
|
||||
def full_domain_validator(request, domain):
|
||||
""" Validation du nom de domaine, extensions dans type de machine, prefixe pas plus long que 63 caractères """
|
||||
HOSTNAME_LABEL_PATTERN = re.compile("(?!-)[A-Z\d-]+(?<!-)$", re.IGNORECASE)
|
||||
dns = domain.name.lower()
|
||||
if len(dns) > 63:
|
||||
messages.error(request,
|
||||
"Le nom de domaine %s est trop long (maximum de 63 caractères)." % dns)
|
||||
return False
|
||||
if not HOSTNAME_LABEL_PATTERN.match(dns):
|
||||
messages.error(request,
|
||||
"Ce nom de domaine %s contient des carractères interdits." % dns)
|
||||
return False
|
||||
return True
|
||||
|
||||
def all_active_interfaces():
|
||||
"""Renvoie l'ensemble des machines autorisées à sortir sur internet """
|
||||
return Interface.objects.filter(machine__in=Machine.objects.filter(user__in=all_has_access()).filter(active=True)).select_related('domain').select_related('machine').select_related('type').select_related('ipv4').select_related('domain__extension').select_related('ipv4__ip_type').distinct()
|
||||
|
@ -99,9 +85,6 @@ def assign_ips(user):
|
|||
|
||||
def free_ip(type):
|
||||
""" Renvoie la liste des ip disponibles """
|
||||
if not type.need_infra:
|
||||
return IpList.objects.filter(interface__isnull=True).filter(ip_type=type).filter(need_infra=False)
|
||||
else:
|
||||
return IpList.objects.filter(interface__isnull=True).filter(ip_type=type)
|
||||
|
||||
def assign_ipv4(interface):
|
||||
|
@ -148,7 +131,6 @@ def new_machine(request, userid):
|
|||
new_machine.user = user
|
||||
new_interface = interface.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)
|
||||
|
@ -195,7 +177,6 @@ def edit_interface(request, interfaceid):
|
|||
new_interface = interface_form.save(commit=False)
|
||||
new_machine = machine_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)
|
||||
|
@ -258,7 +239,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 full_domain_validator(request, new_domain):
|
||||
if free_ip(new_interface.type.ip_type) and not new_interface.ipv4:
|
||||
new_interface = assign_ipv4(new_interface)
|
||||
elif not new_interface.ipv4:
|
||||
|
@ -321,7 +301,7 @@ def edit_iptype(request, iptypeid):
|
|||
except IpType.DoesNotExist:
|
||||
messages.error(request, u"Entrée inexistante" )
|
||||
return redirect("/machines/index_iptype/")
|
||||
iptype = IpTypeForm(request.POST or None, instance=iptype_instance)
|
||||
iptype = EditIpTypeForm(request.POST or None, instance=iptype_instance)
|
||||
if iptype.is_valid():
|
||||
with transaction.atomic(), reversion.create_revision():
|
||||
iptype.save()
|
||||
|
|
|
@ -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,7 +161,6 @@ 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)
|
||||
|
@ -206,7 +205,6 @@ 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)
|
||||
|
|
Loading…
Reference in a new issue