mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 11:23:10 +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"
|
self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4"
|
||||||
if not infra:
|
if not infra:
|
||||||
self.fields['type'].queryset = MachineType.objects.filter(ip_type__in=IpType.objects.filter(need_infra=False))
|
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:
|
else:
|
||||||
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True)
|
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"
|
self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4"
|
||||||
if not infra:
|
if not infra:
|
||||||
self.fields['type'].queryset = MachineType.objects.filter(ip_type__in=IpType.objects.filter(need_infra=False))
|
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:
|
else:
|
||||||
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True)
|
self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True)
|
||||||
|
|
||||||
|
@ -152,14 +152,13 @@ class IpTypeForm(ModelForm):
|
||||||
super(IpTypeForm, self).__init__(*args, **kwargs)
|
super(IpTypeForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['type'].label = 'Type ip à ajouter'
|
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)
|
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 ExtensionForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Extension
|
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.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
from django.db import models
|
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.dispatch import receiver
|
||||||
from django.forms import ValidationError
|
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 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
|
from re2o.settings import MAIN_EXTENSION
|
||||||
|
|
||||||
|
@ -59,6 +60,48 @@ class IpType(models.Model):
|
||||||
domaine_ip = models.GenericIPAddressField(protocol='IPv4')
|
domaine_ip = models.GenericIPAddressField(protocol='IPv4')
|
||||||
domaine_range = models.IntegerField(validators=[MinValueValidator(8), MaxValueValidator(32)])
|
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):
|
def __str__(self):
|
||||||
return self.type
|
return self.type
|
||||||
|
|
||||||
|
@ -133,10 +176,18 @@ class Domain(models.Model):
|
||||||
unique_together = ("name", "extension")
|
unique_together = ("name", "extension")
|
||||||
|
|
||||||
def clean(self):
|
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:
|
if self.interface_parent and self.cname:
|
||||||
raise ValidationError("On ne peut créer à la fois A et CNAME")
|
raise ValidationError("On ne peut créer à la fois A et CNAME")
|
||||||
if self.cname==self:
|
if self.cname==self:
|
||||||
raise ValidationError("On ne peut créer un cname sur lui même")
|
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):
|
def __str__(self):
|
||||||
return str(self.name) + str(self.extension)
|
return str(self.name) + str(self.extension)
|
||||||
|
@ -145,8 +196,20 @@ class IpList(models.Model):
|
||||||
PRETTY_NAME = "Addresses ipv4"
|
PRETTY_NAME = "Addresses ipv4"
|
||||||
|
|
||||||
ipv4 = models.GenericIPAddressField(protocol='IPv4', unique=True)
|
ipv4 = models.GenericIPAddressField(protocol='IPv4', unique=True)
|
||||||
ip_type = models.ForeignKey('IpType', on_delete=models.PROTECT)
|
ip_type = models.ForeignKey('IpType', on_delete=models.CASCADE)
|
||||||
need_infra = models.BooleanField(default=False)
|
|
||||||
|
@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):
|
def __str__(self):
|
||||||
return self.ipv4
|
return self.ipv4
|
||||||
|
@ -173,3 +236,8 @@ def interface_post_delete(sender, **kwargs):
|
||||||
user = interface.machine.user
|
user = interface.machine.user
|
||||||
user.ldap_sync(base=False, access_refresh=False, mac_refresh=True)
|
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
|
import re
|
||||||
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm
|
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 .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from users.models import all_has_access
|
from users.models import all_has_access
|
||||||
from preferences.models import GeneralOption, OptionalMachine
|
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():
|
def all_active_interfaces():
|
||||||
"""Renvoie l'ensemble des machines autorisées à sortir sur internet """
|
"""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()
|
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):
|
def free_ip(type):
|
||||||
""" Renvoie la liste des ip disponibles """
|
""" 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)
|
return IpList.objects.filter(interface__isnull=True).filter(ip_type=type)
|
||||||
|
|
||||||
def assign_ipv4(interface):
|
def assign_ipv4(interface):
|
||||||
|
@ -148,7 +131,6 @@ def new_machine(request, userid):
|
||||||
new_machine.user = user
|
new_machine.user = user
|
||||||
new_interface = interface.save(commit=False)
|
new_interface = interface.save(commit=False)
|
||||||
new_domain = domain.save(commit=False)
|
new_domain = domain.save(commit=False)
|
||||||
if full_domain_validator(request, new_domain):
|
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
new_machine.save()
|
new_machine.save()
|
||||||
reversion.set_user(request.user)
|
reversion.set_user(request.user)
|
||||||
|
@ -195,7 +177,6 @@ def edit_interface(request, interfaceid):
|
||||||
new_interface = interface_form.save(commit=False)
|
new_interface = interface_form.save(commit=False)
|
||||||
new_machine = machine_form.save(commit=False)
|
new_machine = machine_form.save(commit=False)
|
||||||
new_domain = domain_form.save(commit=False)
|
new_domain = domain_form.save(commit=False)
|
||||||
if full_domain_validator(request, new_domain):
|
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
new_machine.save()
|
new_machine.save()
|
||||||
reversion.set_user(request.user)
|
reversion.set_user(request.user)
|
||||||
|
@ -258,7 +239,6 @@ def new_interface(request, machineid):
|
||||||
new_interface = interface_form.save(commit=False)
|
new_interface = interface_form.save(commit=False)
|
||||||
new_interface.machine = machine
|
new_interface.machine = machine
|
||||||
new_domain = domain_form.save(commit=False)
|
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:
|
if free_ip(new_interface.type.ip_type) and not new_interface.ipv4:
|
||||||
new_interface = assign_ipv4(new_interface)
|
new_interface = assign_ipv4(new_interface)
|
||||||
elif not new_interface.ipv4:
|
elif not new_interface.ipv4:
|
||||||
|
@ -321,7 +301,7 @@ def edit_iptype(request, iptypeid):
|
||||||
except IpType.DoesNotExist:
|
except IpType.DoesNotExist:
|
||||||
messages.error(request, u"Entrée inexistante" )
|
messages.error(request, u"Entrée inexistante" )
|
||||||
return redirect("/machines/index_iptype/")
|
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():
|
if iptype.is_valid():
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
iptype.save()
|
iptype.save()
|
||||||
|
|
|
@ -35,7 +35,7 @@ from users.views import form
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
from machines.forms import AliasForm, NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm
|
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 preferences.models import GeneralOption
|
||||||
|
|
||||||
from re2o.settings import ASSO_PSEUDO
|
from re2o.settings import ASSO_PSEUDO
|
||||||
|
@ -161,7 +161,6 @@ def new_switch(request):
|
||||||
new_interface = interface.save(commit=False)
|
new_interface = interface.save(commit=False)
|
||||||
new_switch = switch.save(commit=False)
|
new_switch = switch.save(commit=False)
|
||||||
new_domain = domain.save(commit=False)
|
new_domain = domain.save(commit=False)
|
||||||
if full_domain_validator(request, new_domain):
|
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
new_machine.save()
|
new_machine.save()
|
||||||
reversion.set_user(request.user)
|
reversion.set_user(request.user)
|
||||||
|
@ -206,7 +205,6 @@ def edit_switch(request, switch_id):
|
||||||
new_machine = machine_form.save(commit=False)
|
new_machine = machine_form.save(commit=False)
|
||||||
new_switch = switch_form.save(commit=False)
|
new_switch = switch_form.save(commit=False)
|
||||||
new_domain = domain_form.save(commit=False)
|
new_domain = domain_form.save(commit=False)
|
||||||
if full_domain_validator(request, new_domain):
|
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
new_machine.save()
|
new_machine.save()
|
||||||
reversion.set_user(request.user)
|
reversion.set_user(request.user)
|
||||||
|
|
Loading…
Reference in a new issue