diff --git a/logs/views.py b/logs/views.py index 116e8350..a1dfb361 100644 --- a/logs/views.py +++ b/logs/views.py @@ -19,7 +19,7 @@ from reversion.models import Version from users.models import User, ServiceUser, Right, School, ListRight, ListShell, Ban, Whitelist from cotisations.models import Facture, Vente, Article, Banque, Paiement, Cotisation -from machines.models import Machine, MachineType, IpType, Extension, Interface, Alias, IpList +from machines.models import Machine, MachineType, IpType, Extension, Interface, Domain, IpList from topologie.models import Switch, Port, Room from re2o.settings import PAGINATION_NUMBER, PAGINATION_LARGE_NUMBER @@ -99,7 +99,7 @@ def stats_models(request): 'typeip' : [IpType.PRETTY_NAME, IpType.objects.count()], 'extension' : [Extension.PRETTY_NAME, Extension.objects.count()], 'interface' : [Interface.PRETTY_NAME, Interface.objects.count()], - 'alias' : [Alias.PRETTY_NAME, Alias.objects.count()], + 'alias' : [Domain.PRETTY_NAME, Domain.objects.exclude(cname=None).count()], 'iplist' : [IpList.PRETTY_NAME, IpList.objects.count()], }, 'Topologie' : { diff --git a/machines/admin.py b/machines/admin.py index 23fd068e..1eddaa38 100644 --- a/machines/admin.py +++ b/machines/admin.py @@ -26,7 +26,7 @@ class IpListAdmin(VersionAdmin): list_display = ('ipv4','ip_type') class InterfaceAdmin(VersionAdmin): - list_display = ('machine','type','dns','mac_address','ipv4','details') + list_display = ('machine','type','mac_address','ipv4','details') class DomainAdmin(VersionAdmin): list_display = ('interface_parent', 'name', 'extension', 'cname') diff --git a/machines/forms.py b/machines/forms.py index 140eacfd..4b65c609 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -1,6 +1,6 @@ from django.forms import ModelForm, Form, ValidationError from django import forms -from .models import Alias, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, IpType +from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, IpType from django.db.models import Q class EditMachineForm(ModelForm): @@ -27,14 +27,13 @@ class EditInterfaceForm(ModelForm): def __init__(self, *args, **kwargs): super(EditInterfaceForm, self).__init__(*args, **kwargs) - self.fields['dns'].label = 'Nom dns de la machine' self.fields['mac_address'].label = 'Adresse mac' self.fields['type'].label = 'Type de machine' self.fields['type'].empty_label = "Séléctionner un type de machine" class AddInterfaceForm(EditInterfaceForm): class Meta(EditInterfaceForm.Meta): - fields = ['ipv4','mac_address','dns','type','details'] + fields = ['ipv4','mac_address','type','details'] def __init__(self, *args, **kwargs): infra = kwargs.pop('infra') @@ -48,11 +47,11 @@ class AddInterfaceForm(EditInterfaceForm): class NewInterfaceForm(EditInterfaceForm): class Meta(EditInterfaceForm.Meta): - fields = ['mac_address','dns','type','details'] + fields = ['mac_address','type','details'] class BaseEditInterfaceForm(EditInterfaceForm): class Meta(EditInterfaceForm.Meta): - fields = ['ipv4','mac_address','dns','type','details'] + fields = ['ipv4','mac_address','type','details'] def __init__(self, *args, **kwargs): infra = kwargs.pop('infra') @@ -66,8 +65,8 @@ class BaseEditInterfaceForm(EditInterfaceForm): class AliasForm(ModelForm): class Meta: - model = Alias - fields = ['alias','extension'] + model = Domain + fields = ['name','extension'] def __init__(self, *args, **kwargs): infra = kwargs.pop('infra') @@ -76,16 +75,16 @@ class AliasForm(ModelForm): self.fields['extension'].queryset = Extension.objects.filter(need_infra=False) class DelAliasForm(ModelForm): - alias = forms.ModelMultipleChoiceField(queryset=Alias.objects.all(), label="Alias actuels", widget=forms.CheckboxSelectMultiple) + alias = forms.ModelMultipleChoiceField(queryset=Domain.objects.all(), label="Alias actuels", widget=forms.CheckboxSelectMultiple) def __init__(self, *args, **kwargs): interface = kwargs.pop('interface') super(DelAliasForm, self).__init__(*args, **kwargs) - self.fields['alias'].queryset = Alias.objects.filter(interface_parent=interface) + self.fields['alias'].queryset = Domain.objects.filter(cname__in=Domain.objects.filter(interface_parent=interface)) class Meta: - exclude = ['interface_parent', 'alias', 'extension'] - model = Alias + exclude = ['interface_parent', 'name', 'extension', 'cname'] + model = Domain class MachineTypeForm(ModelForm): class Meta: diff --git a/machines/migrations/0040_remove_interface_dns.py b/machines/migrations/0040_remove_interface_dns.py new file mode 100644 index 00000000..46e926fb --- /dev/null +++ b/machines/migrations/0040_remove_interface_dns.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0039_auto_20161224_1732'), + ] + + operations = [ + migrations.RemoveField( + model_name='interface', + name='dns', + ), + ] diff --git a/machines/models.py b/machines/models.py index 791b4575..315627f7 100644 --- a/machines/models.py +++ b/machines/models.py @@ -78,7 +78,6 @@ class Interface(models.Model): machine = models.ForeignKey('Machine', on_delete=models.CASCADE) type = models.ForeignKey('MachineType', on_delete=models.PROTECT) details = models.CharField(max_length=255, blank=True) - dns = models.CharField(help_text="Obligatoire et unique, ne doit pas comporter de points", max_length=255, unique=True) def is_active(self): """ Renvoie si une interface doit avoir accès ou non """ @@ -93,7 +92,11 @@ class Interface(models.Model): self.mac_address = str(EUI(self.mac_address)) or None def __str__(self): - return self.domain_set.all().first() + try: + domain = self.domain + except: + domain = None + return str(domain) class Domain(models.Model): PRETTY_NAME = "Domaine dns" @@ -109,7 +112,7 @@ class Domain(models.Model): def clean(self): if self.interface_parent and self.cname: raise ValidationError("On ne peut créer à la fois A et CNAME") - if self.related==self: + if self.cname==self: raise ValidationError("On ne peut créer un cname sur lui même") def __str__(self): diff --git a/machines/serializers.py b/machines/serializers.py index b19294c4..df6edd47 100644 --- a/machines/serializers.py +++ b/machines/serializers.py @@ -1,7 +1,7 @@ #Augustin Lemesle from rest_framework import serializers -from machines.models import Interface, IpType, Extension, IpList, MachineType, Alias, Mx, Ns +from machines.models import Interface, IpType, Extension, IpList, MachineType, Domain, Mx, Ns class IpTypeField(serializers.RelatedField): def to_representation(self, value): @@ -17,10 +17,14 @@ class IpListSerializer(serializers.ModelSerializer): class InterfaceSerializer(serializers.ModelSerializer): ipv4 = IpListSerializer(read_only=True) mac_address = serializers.SerializerMethodField('get_macaddress') + dns = serializers.SerializerMethodField('get_dns') class Meta: model = Interface - fields = ('ipv4', 'mac_address', 'dns') + fields = ('ipv4', 'mac_address') + + def get_dns(self, obj): + return obj.domain_set.all().first() def get_macaddress(self, obj): return str(obj.mac_address) @@ -74,16 +78,20 @@ class NsSerializer(serializers.ModelSerializer): def get_interface_name(self, obj): return obj.interface.dns + obj.interface.ipv4.ip_type.extension.name -class AliasSerializer(serializers.ModelSerializer): +class DomainSerializer(serializers.ModelSerializer): interface_parent = serializers.SerializerMethodField('get_interface_name') extension = serializers.SerializerMethodField('get_zone_name') + cname = serializers.SerializerMethodField('get_cname') class Meta: - model = Alias - fields = ('interface_parent', 'alias', 'extension') + model = Domain + fields = ('interface_parent', 'name', 'extension', 'cname') def get_zone_name(self, obj): return obj.extension.name + def get_cname(self, obj): + return obj.cname.name + obj.cname.extension.name + def get_interface_name(self, obj): - return obj.interface_parent.dns + obj.interface_parent.ipv4.ip_type.extension.name + return obj.name + obj.extension.name diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index e1c11fe3..b238acfa 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -28,13 +28,13 @@ {% endif %} - {% if interface.alias_set.all %} + {% if interface.domain.related_domain.all %} {% else %} - {{ interface.dns }} + {{ interface.domain }} {% endif %} {{ interface.type }} diff --git a/machines/templates/machines/machine.html b/machines/templates/machines/machine.html index a8d287f6..f1ae661d 100644 --- a/machines/templates/machines/machine.html +++ b/machines/templates/machines/machine.html @@ -19,6 +19,9 @@ {% if interfaceform %} {% bootstrap_form interfaceform %} {% endif %} + {% if domainform %} + {% bootstrap_form domainform %} + {% endif %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
diff --git a/machines/views.py b/machines/views.py index 7b07872d..69abf6dc 100644 --- a/machines/views.py +++ b/machines/views.py @@ -16,21 +16,21 @@ from django.contrib.auth import authenticate, login from django.views.decorators.csrf import csrf_exempt from rest_framework.renderers import JSONRenderer -from machines.serializers import InterfaceSerializer, TypeSerializer, AliasSerializer, MxSerializer, ExtensionSerializer, NsSerializer +from machines.serializers import InterfaceSerializer, TypeSerializer, DomainSerializer, MxSerializer, ExtensionSerializer, NsSerializer from reversion import revisions as reversion 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 .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Alias +from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain from users.models import User from re2o.settings import PAGINATION_NUMBER, PAGINATION_LARGE_NUMBER, MAX_INTERFACES, MAX_ALIAS -def full_domain_validator(request, interface): +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-]+(? 63: messages.error(request, "Le nom de domaine %s est trop long (maximum de 63 caractères)." % dns) @@ -99,11 +99,13 @@ def new_machine(request, userid): return redirect("/users/profil/" + str(request.user.id)) machine = NewMachineForm(request.POST or None) interface = AddInterfaceForm(request.POST or None, infra=request.user.has_perms(('infra',))) + domain = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',))) if machine.is_valid() and interface.is_valid(): new_machine = machine.save(commit=False) new_machine.user = user new_interface = interface.save(commit=False) - if full_domain_validator(request, new_interface): + 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) @@ -117,9 +119,14 @@ def new_machine(request, userid): 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") messages.success(request, "La machine a été crée") return redirect("/users/profil/" + userid) - return form({'machineform': machine, 'interfaceform': interface}, 'machines/machine.html', request) + return form({'machineform': machine, 'interfaceform': interface, 'domainform': domain}, 'machines/machine.html', request) @login_required def edit_interface(request, interfaceid): @@ -137,10 +144,12 @@ def edit_interface(request, interfaceid): else: machine_form = EditMachineForm(request.POST or None, instance=interface.machine) interface_form = EditInterfaceForm(request.POST or None, instance=interface) - if machine_form.is_valid() and interface_form.is_valid(): + domain_form = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',)), instance=interface.domain) + if machine_form.is_valid() and interface_form.is_valid() and domain_form.is_valid(): new_interface = interface_form.save(commit=False) new_machine = machine_form.save(commit=False) - if full_domain_validator(request, new_interface): + 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) @@ -151,9 +160,13 @@ def edit_interface(request, interfaceid): 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)) messages.success(request, "La machine a été modifiée") return redirect("/users/profil/" + str(interface.machine.user.id)) - return form({'machineform': machine_form, 'interfaceform': interface_form}, 'machines/machine.html', request) + return form({'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form}, 'machines/machine.html', request) @login_required def del_machine(request, machineid): @@ -189,10 +202,12 @@ def new_interface(request, machineid): messages.error(request, "Vous avez atteint le maximum d'interfaces autorisées que vous pouvez créer vous même (%s) " % MAX_INTERFACES) return redirect("/users/profil/" + str(request.user.id)) interface_form = AddInterfaceForm(request.POST or None, infra=request.user.has_perms(('infra',))) + domain_form = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',))) if interface_form.is_valid(): new_interface = interface_form.save(commit=False) new_interface.machine = machine - if full_domain_validator(request, new_interface): + 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: @@ -201,9 +216,14 @@ def new_interface(request, machineid): 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") messages.success(request, "L'interface a été ajoutée") return redirect("/users/profil/" + str(machine.user.id)) - return form({'interfaceform': interface_form}, 'machines/machine.html', request) + return form({'interfaceform': interface_form, 'domainform': domain_form}, 'machines/machine.html', request) @login_required def del_interface(request, interfaceid): @@ -478,13 +498,13 @@ def add_alias(request, interfaceid): if interface.machine.user != request.user: messages.error(request, "Vous ne pouvez pas ajouter un alias à une machine d'un autre user que vous sans droit") return redirect("/users/profil/" + str(request.user.id)) - if Alias.objects.filter(interface_parent__in=interface.machine.user.user_interfaces()).count() >= MAX_ALIAS: + if Domain.objects.filter(cname__in=Domain.objects.filter(interface_parent__in=interface.machine.user.user_interfaces())).count() >= MAX_ALIAS: messages.error(request, "Vous avez atteint le maximum d'alias autorisées que vous pouvez créer vous même (%s) " % MAX_ALIAS) return redirect("/users/profil/" + str(request.user.id)) alias = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',))) if alias.is_valid(): alias = alias.save(commit=False) - alias.interface_parent = interface + alias.cname = interface.domain with transaction.atomic(), reversion.create_revision(): alias.save() reversion.set_user(request.user) @@ -496,11 +516,11 @@ def add_alias(request, interfaceid): @login_required def edit_alias(request, aliasid): try: - alias_instance = Alias.objects.get(pk=aliasid) - except Alias.DoesNotExist: + alias_instance = Domain.objects.get(pk=aliasid) + except Domain.DoesNotExist: messages.error(request, u"Entrée inexistante" ) return redirect("/machines/index_extension/") - if not request.user.has_perms(('cableur',)) and alias_instance.interface_parent.machine.user != request.user: + if not request.user.has_perms(('cableur',)) and alias_instance.cname.interface_parent.machine.user != request.user: messages.error(request, "Vous ne pouvez pas ajouter un alias à une machine d'un autre user que vous sans droit") return redirect("/users/profil/" + str(request.user.id)) alias = AliasForm(request.POST or None, instance=alias_instance, infra=request.user.has_perms(('infra',))) @@ -510,7 +530,7 @@ def edit_alias(request, aliasid): reversion.set_user(request.user) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in alias.changed_data)) messages.success(request, "Alias modifié") - return redirect("/machines/index_alias/" + str(alias_instance.interface_parent.id)) + return redirect("/machines/index_alias/" + str(alias_instance.cname.interface_parent.id)) return form({'machineform': alias}, 'machines/machine.html', request) @login_required @@ -583,7 +603,7 @@ def index_alias(request, interfaceid): if not request.user.has_perms(('cableur',)) and interface.machine.user != request.user: messages.error(request, "Vous ne pouvez pas éditer une machine d'un autre user que vous sans droit") return redirect("/users/profil/" + str(request.user.id)) - alias_list = Alias.objects.filter(interface_parent=interface).order_by('alias') + alias_list = Domain.objects.filter(cname=Domain.objects.filter(interface_parent=interface)).order_by('name') return render(request, 'machines/index_alias.html', {'alias_list':alias_list, 'interface_id': interfaceid}) @login_required @@ -608,11 +628,11 @@ def history(request, object, id): return redirect("/users/profil/" + str(request.user.id)) elif object == 'alias': try: - object_instance = Alias.objects.get(pk=id) - except Alias.DoesNotExist: + object_instance = Domain.objects.get(pk=id) + except Domain.DoesNotExist: messages.error(request, "Alias inexistant") return redirect("/machines/") - if not request.user.has_perms(('cableur',)) and object_instance.interface_parent.machine.user != request.user: + if not request.user.has_perms(('cableur',)) and object_instance.cname.interface_parent.machine.user != request.user: messages.error(request, "Vous ne pouvez pas afficher l'historique d'un alias d'un autre user que vous sans droit cableur") return redirect("/users/profil/" + str(request.user.id)) elif object == 'machinetype' and request.user.has_perms(('cableur',)): @@ -686,8 +706,8 @@ def interface_list(request): @login_required @permission_required('serveur') def alias(request): - alias = Alias.objects.filter(interface_parent__in=Interface.objects.exclude(ipv4=None)) - seria = AliasSerializer(alias, many=True) + alias = Domain.objects.filter(interface_parent=None).filter(cname=Domain.objects.filter(interface_parent__in=Interface.objects.exclude(ipv4=None))) + seria = DomainSerializer(alias, many=True) return JSONResponse(seria.data) @csrf_exempt diff --git a/search/views.py b/search/views.py index fc281766..8d5651cc 100644 --- a/search/views.py +++ b/search/views.py @@ -55,7 +55,7 @@ def search_result(search, type, request): if i == '0': recherche['users_list'] = User.objects.filter((Q(room__name__icontains = search) | Q(pseudo__icontains = search) | Q(name__icontains = search) | Q(surname__icontains = search)) & query1).order_by('state', 'surname') if i == '1': - data = Interface.objects.filter(Q(machine__user__pseudo__icontains = search) | Q(machine__user__name__icontains = search) | Q(machine__user__surname__icontains = search) | Q(dns__icontains = search) | Q(mac_address__icontains = search) | Q(ipv4__ipv4__icontains = search)) + data = Interface.objects.filter(Q(machine__user__pseudo__icontains = search) | Q(machine__user__name__icontains = search) | Q(machine__user__surname__icontains = search) | Q(mac_address__icontains = search) | Q(ipv4__ipv4__icontains = search)) for d in data: recherche['machines_list'].append(d.machine) if i == '2':