From 80b3ac34204cf91bec3a4c7a5d8fd44d169b9c96 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 28 Sep 2017 17:19:33 +0200 Subject: [PATCH 01/21] =?UTF-8?q?Cr=C3=A9e=20un=20mod=C3=A8le=20pour=20une?= =?UTF-8?q?=20liste=20de=20ports=20et=20un=20autre=20pour=20repr=C3=A9sent?= =?UTF-8?q?er=20un=20port=20ou=20une=20plage=20de=20ports.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0058_auto_20170928_1711.py | 37 +++++++++++++++++++ machines/migrations/0059_port_protocole.py | 20 ++++++++++ machines/models.py | 37 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 machines/migrations/0058_auto_20170928_1711.py create mode 100644 machines/migrations/0059_port_protocole.py diff --git a/machines/migrations/0058_auto_20170928_1711.py b/machines/migrations/0058_auto_20170928_1711.py new file mode 100644 index 00000000..41224de1 --- /dev/null +++ b/machines/migrations/0058_auto_20170928_1711.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-09-28 15:11 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0057_nas_autocapture_mac'), + ] + + operations = [ + migrations.CreateModel( + name='Port', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('begin', models.IntegerField()), + ('end', models.IntegerField()), + ], + ), + migrations.CreateModel( + name='PortList', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(help_text='Nom de la configuration des ports.', max_length=255)), + ('interfaces', models.ManyToManyField(to='machines.Interface')), + ], + ), + migrations.AddField( + model_name='port', + name='port_list', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.PortList'), + ), + ] diff --git a/machines/migrations/0059_port_protocole.py b/machines/migrations/0059_port_protocole.py new file mode 100644 index 00000000..fc43bdb0 --- /dev/null +++ b/machines/migrations/0059_port_protocole.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-09-28 16:03 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0058_auto_20170928_1711'), + ] + + operations = [ + migrations.AddField( + model_name='port', + name='protocole', + field=models.CharField(choices=[('T', 'TCP'), ('U', 'UDP')], default='T', max_length=1), + ), + ] diff --git a/machines/models.py b/machines/models.py index 8eff89fc..4dc0e3ad 100644 --- a/machines/models.py +++ b/machines/models.py @@ -406,6 +406,43 @@ class Service_link(models.Model): def __str__(self): return str(self.server) + " " + str(self.service) + +class PortList(models.Model): + """Liste des ports ouverts sur une interface.""" + interfaces = models.ManyToManyField('Interface') + name = models.CharField(help_text="Nom de la configuration des ports.", max_length=255) + + def __str__(self): + return ', '.join(map(str, self.port_set.all())) + +class Port(models.Model): + """ + Représente un simple port ou une plage de ports. + + Les ports de la plage sont compris entre begin et en inclus. + Si begin == end alors on ne représente qu'un seul port. + """ + TCP = 'T' + UDP = 'U' + begin = models.IntegerField() + end = models.IntegerField() + port_list = models.ForeignKey('PortList', on_delete=models.CASCADE) + protocole = models.CharField( + max_length=1, + choices=( + (TCP, 'TCP'), + (UDP, 'UDP'), + ), + default=TCP, + ) + + def __str__(self): + beg = self.protocole + ' : ' + if self.begin == self.end : + return beg + str(self.begin) + return beg + '-'.join([str(self.begin), str(self.end)]) + + @receiver(post_save, sender=Machine) def machine_post_save(sender, **kwargs): user = kwargs['instance'].user From 100087640ae92c0c309998f541cd27d729f7df85 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 29 Sep 2017 22:28:48 +0200 Subject: [PATCH 02/21] Affichage basique des configurations de ports disponibles. --- machines/models.py | 11 ++++-- .../templates/machines/index_portlist.html | 37 +++++++++++++++++++ machines/templates/machines/sidebar.html | 6 +++ machines/urls.py | 1 + machines/views.py | 8 +++- 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 machines/templates/machines/index_portlist.html diff --git a/machines/models.py b/machines/models.py index 4dc0e3ad..ff5dd1e9 100644 --- a/machines/models.py +++ b/machines/models.py @@ -415,6 +415,12 @@ class PortList(models.Model): def __str__(self): return ', '.join(map(str, self.port_set.all())) + def tcp_ports(self): + return self.port_set.filter(protocole=Port.TCP) + + def udp_ports(self): + return self.port_set.filter(protocole=Port.UDP) + class Port(models.Model): """ Représente un simple port ou une plage de ports. @@ -437,10 +443,9 @@ class Port(models.Model): ) def __str__(self): - beg = self.protocole + ' : ' if self.begin == self.end : - return beg + str(self.begin) - return beg + '-'.join([str(self.begin), str(self.end)]) + return str(self.begin) + return '-'.join([str(self.begin), str(self.end)]) @receiver(post_save, sender=Machine) diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html new file mode 100644 index 00000000..1ba3a61f --- /dev/null +++ b/machines/templates/machines/index_portlist.html @@ -0,0 +1,37 @@ +{% extends "machines/sidebar.html" %} + +{% load bootstrap3 %} + +{% block title %}Configuration de ports{% endblock %} + +{% block content %} +

Liste des configurations de ports

+ Ajouter une configuration + + + + + + + + + + {% for pl in port_list %} + + + + + + + {%endfor%} +
NomTCPUDP
{{pl.name}}{{pl.tcp_ports}}{{pl.udp_ports}} + {%comment%} + {% include 'buttons/suppr.html' href='machines:del-portlist' id=pl.id %} + {% include 'buttons/edit.html' href='machines:edit-portlist' id=pl.id %} + {%endcomment%} +
+
+
+
+ +{% endblock %} diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index 7334f628..a0d6948a 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -55,4 +55,10 @@ with this program; if not, write to the Free Software Foundation, Inc., Services (dhcp, dns...) {% endif %} + {% if is_bureau %} + + + Configuration de ports + + {%endif%} {% endblock %} diff --git a/machines/urls.py b/machines/urls.py index cdf3d5fb..4962609e 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -92,4 +92,5 @@ urlpatterns = [ url(r'^rest/text/$', views.text, name='text'), url(r'^rest/zones/$', views.zones, name='zones'), url(r'^rest/service_servers/$', views.service_servers, name='service-servers'), + url(r'index_portlist/$', views.index_portlist, name='index-portlist'), ] diff --git a/machines/views.py b/machines/views.py index 4268519b..4cb1149f 100644 --- a/machines/views.py +++ b/machines/views.py @@ -48,7 +48,7 @@ from reversion.models import Version import re from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm -from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text +from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, PortList from users.models import User from users.models import all_has_access from preferences.models import GeneralOption, OptionalMachine @@ -912,6 +912,12 @@ def history(request, object, id): return render(request, 're2o/history.html', {'reversions': reversions, 'object': object_instance}) +@login_required +@permission_required('bureau') +def index_portlist(request): + port_list = PortList.objects.all().order_by('name') + return render(request, "machines/index_portlist.html", {'port_list':port_list}) + """ Framework Rest """ class JSONResponse(HttpResponse): From d0a0a70e6e4395231452ca0bb8a3bd207269d71f Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 30 Sep 2017 10:04:18 +0200 Subject: [PATCH 03/21] =?UTF-8?q?Affichage=20de=20la=20page=20d'=C3=A9diti?= =?UTF-8?q?on=20d'une=20liste=20de=20ports.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 9 ++++++++- machines/models.py | 5 +++++ machines/templates/machines/index_portlist.html | 6 +++--- machines/urls.py | 1 + machines/views.py | 12 +++++++++++- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/machines/forms.py b/machines/forms.py index cd4ac87d..afe781f1 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -24,7 +24,7 @@ from __future__ import unicode_literals from django.forms import ModelForm, Form, ValidationError from django import forms -from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType +from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType, PortList from django.db.models import Q from django.core.validators import validate_email @@ -229,5 +229,12 @@ class VlanForm(ModelForm): class DelVlanForm(Form): vlan = forms.ModelMultipleChoiceField(queryset=Vlan.objects.all(), label="Vlan actuels", widget=forms.CheckboxSelectMultiple) +class EditPortListForm(ModelForm): + tcp_ports = forms.CharField(required=False, label="Ports TCP") + udp_ports = forms.CharField(required=False, label="Ports UDP") + # interfaces = forms.ModelMultipleChoiceField(queryset=Interface.objects.filter(Q(has_public_ip=True)), label="Interface", widget=forms.CheckboxSelectMultiple) + class Meta: + model = PortList + fields = ['name'] diff --git a/machines/models.py b/machines/models.py index ff5dd1e9..91e16ab9 100644 --- a/machines/models.py +++ b/machines/models.py @@ -223,6 +223,7 @@ 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) + has_public_ip = False @cached_property def is_active(self): @@ -278,6 +279,7 @@ class Interface(models.Model): domain = None return str(domain) + class Domain(models.Model): PRETTY_NAME = "Domaine dns" @@ -447,6 +449,9 @@ class Port(models.Model): return str(self.begin) return '-'.join([str(self.begin), str(self.end)]) + def show_port(self): + return str(self) + @receiver(post_save, sender=Machine) def machine_post_save(sender, **kwargs): diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html index 1ba3a61f..ce48e249 100644 --- a/machines/templates/machines/index_portlist.html +++ b/machines/templates/machines/index_portlist.html @@ -19,13 +19,13 @@ {% for pl in port_list %} {{pl.name}} - {{pl.tcp_ports}} - {{pl.udp_ports}} + {% for p in pl.tcp_ports%}{{p.show_port}}, {%endfor%} + {% for p in pl.udp_ports%}{{p.show_port}}, {%endfor%} {%comment%} {% include 'buttons/suppr.html' href='machines:del-portlist' id=pl.id %} - {% include 'buttons/edit.html' href='machines:edit-portlist' id=pl.id %} {%endcomment%} + {% include 'buttons/edit.html' with href='machines:edit-portlist' id=pl.id %} {%endfor%} diff --git a/machines/urls.py b/machines/urls.py index 4962609e..29f7668f 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -93,4 +93,5 @@ urlpatterns = [ url(r'^rest/zones/$', views.zones, name='zones'), url(r'^rest/service_servers/$', views.service_servers, name='service-servers'), url(r'index_portlist/$', views.index_portlist, name='index-portlist'), + url(r'^edit_portlist/(?P[0-9]+)$', views.edit_portlist, name='edit-portlist'), ] diff --git a/machines/views.py b/machines/views.py index 4cb1149f..32b04c2e 100644 --- a/machines/views.py +++ b/machines/views.py @@ -48,6 +48,7 @@ from reversion.models import Version import re from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm +from .forms import EditPortListForm from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, PortList from users.models import User from users.models import all_has_access @@ -913,11 +914,20 @@ def history(request, object, id): @login_required -@permission_required('bureau') +@permission_required('cableur') def index_portlist(request): port_list = PortList.objects.all().order_by('name') return render(request, "machines/index_portlist.html", {'port_list':port_list}) +@login_required +@permission_required('bureau') +def edit_portlist(request, pk): + port_list_instance = get_object_or_404(PortList, pk=pk) + port_list = EditPortListForm(request.POST or None, instance=port_list_instance) + if port_list.is_valid(): + return redirect("/machines/index_portlist/") + return form({'machineform' : port_list}, 'machines/machine.html', request) + """ Framework Rest """ class JSONResponse(HttpResponse): From 87a5800b3173ed514a4d84f96a1531badcfa08c2 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 11:39:39 +0200 Subject: [PATCH 04/21] =?UTF-8?q?Gestion=20de=20l'ouverture=20en=20entr?= =?UTF-8?q?=C3=A9e=20et=20en=20sortie.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 7 +++--- machines/migrations/0060_port_io.py | 20 +++++++++++++++ machines/models.py | 25 ++++++++++++++++--- .../templates/machines/index_portlist.html | 12 ++++++--- 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 machines/migrations/0060_port_io.py diff --git a/machines/forms.py b/machines/forms.py index afe781f1..a611fa98 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -230,9 +230,10 @@ class DelVlanForm(Form): vlan = forms.ModelMultipleChoiceField(queryset=Vlan.objects.all(), label="Vlan actuels", widget=forms.CheckboxSelectMultiple) class EditPortListForm(ModelForm): - tcp_ports = forms.CharField(required=False, label="Ports TCP") - udp_ports = forms.CharField(required=False, label="Ports UDP") - # interfaces = forms.ModelMultipleChoiceField(queryset=Interface.objects.filter(Q(has_public_ip=True)), label="Interface", widget=forms.CheckboxSelectMultiple) + tcp_ports_in = forms.CharField(required=False, label="Ports TCP (entrée)") + udp_ports_in = forms.CharField(required=False, label="Ports UDP (entrée)") + tcp_ports_out = forms.CharField(required=False, label="Ports TCP (sortie)") + udp_ports_out = forms.CharField(required=False, label="Ports UDP (sortie)") class Meta: model = PortList fields = ['name'] diff --git a/machines/migrations/0060_port_io.py b/machines/migrations/0060_port_io.py new file mode 100644 index 00000000..0d890b56 --- /dev/null +++ b/machines/migrations/0060_port_io.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-10-01 09:30 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0059_port_protocole'), + ] + + operations = [ + migrations.AddField( + model_name='port', + name='io', + field=models.CharField(choices=[('I', 'IN'), ('O', 'OUT')], default='O', max_length=1), + ), + ] diff --git a/machines/models.py b/machines/models.py index 91e16ab9..949d9608 100644 --- a/machines/models.py +++ b/machines/models.py @@ -417,11 +417,18 @@ class PortList(models.Model): def __str__(self): return ', '.join(map(str, self.port_set.all())) - def tcp_ports(self): - return self.port_set.filter(protocole=Port.TCP) + def tcp_ports_in(self): + return self.port_set.filter(protocole=Port.TCP, io=Port.IN) - def udp_ports(self): - return self.port_set.filter(protocole=Port.UDP) + def udp_ports_in(self): + return self.port_set.filter(protocole=Port.UDP, io=Port.IN) + + def tcp_ports_out(self): + return self.port_set.filter(protocole=Port.TCP, io=Port.OUT) + + def udp_ports_out(self): + return self.port_set.filter(protocole=Port.UDP, io=Port.OUT) + class Port(models.Model): """ @@ -432,6 +439,8 @@ class Port(models.Model): """ TCP = 'T' UDP = 'U' + IN = 'I' + OUT = 'O' begin = models.IntegerField() end = models.IntegerField() port_list = models.ForeignKey('PortList', on_delete=models.CASCADE) @@ -443,6 +452,14 @@ class Port(models.Model): ), default=TCP, ) + io = models.CharField( + max_length=1, + choices=( + (IN, 'IN'), + (OUT, 'OUT'), + ), + default=OUT, + ) def __str__(self): if self.begin == self.end : diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html index ce48e249..81847af1 100644 --- a/machines/templates/machines/index_portlist.html +++ b/machines/templates/machines/index_portlist.html @@ -11,16 +11,20 @@ Nom - TCP - UDP + TCP (entrée) + TCP (sortie) + UDP (entrée) + UDP (sortie) {% for pl in port_list %} {{pl.name}} - {% for p in pl.tcp_ports%}{{p.show_port}}, {%endfor%} - {% for p in pl.udp_ports%}{{p.show_port}}, {%endfor%} + {% for p in pl.tcp_ports_in %}{{p.show_port}}, {%endfor%} + {% for p in pl.tcp_ports_out %}{{p.show_port}}, {%endfor%} + {% for p in pl.udp_ports_in %}{{p.show_port}}, {%endfor%} + {% for p in pl.udp_ports_out %}{{p.show_port}}, {%endfor%} {%comment%} {% include 'buttons/suppr.html' href='machines:del-portlist' id=pl.id %} From 68600eddecf0fce5c233b1d0a323f1ba4d25c01d Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 16:42:55 +0200 Subject: [PATCH 05/21] =?UTF-8?q?=C3=89dition=20des=20listes=20de=20ports.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++- machines/views.py | 5 +++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/machines/forms.py b/machines/forms.py index a611fa98..dec2cad2 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -22,9 +22,11 @@ from __future__ import unicode_literals +import re + from django.forms import ModelForm, Form, ValidationError from django import forms -from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType, PortList +from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType, PortList, Port from django.db.models import Q from django.core.validators import validate_email @@ -238,4 +240,57 @@ class EditPortListForm(ModelForm): model = PortList fields = ['name'] + def __init__(self, *args, **kwargs): + super(EditPortListForm, self).__init__(*args, **kwargs) + self.fields['name'].label = "Nom de la liste" + if 'instance' in kwargs.keys(): + p = kwargs['instance'] + self.fields['tcp_ports_in'].initial = ', '.join(map(str, p.tcp_ports_in())) + self.fields['tcp_ports_out'].initial = ', '.join(map(str, p.tcp_ports_out())) + self.fields['udp_ports_in'].initial = ', '.join(map(str, p.udp_ports_in())) + self.fields['udp_ports_out'].initial = ', '.join(map(str, p.udp_ports_out())) + + def save(self, commit=False): + """ + Sauvegarde l'instance. Le commit est obligatoire à cause des ForeignKey. + """ + instance = super(EditPortListForm, self).save(commit=False) + + # Suppression des anciens ports. + for port in instance.port_set.all(): + port.delete() + + split = r',\s+' + ip_range = r'\d+-\d+' + def add_port(string, protocole, mode): + for p in re.split(split, string): + if not p: + continue + if re.match(ip_range, p): + a,b = p.split('-') + a,b = int(a), int(b) + begin,end = min(a,b),max(a,b) + else: + begin = end = int(p.strip()) + port = Port() + port.begin = begin + port.end = end + port.port_list = instance + port.protocole = protocole + port.io = mode + port.save() + + # Ajout des ports TCP en entrée + add_port(self.cleaned_data['tcp_ports_in'], Port.TCP, Port.IN) + # Ajout des ports TCP en sortie + add_port(self.cleaned_data['tcp_ports_out'], Port.TCP, Port.OUT) + # Ajout des ports UDP en entrée + add_port(self.cleaned_data['tcp_ports_in'], Port.UDP, Port.IN) + # Ajout des ports UDP en sortie + add_port(self.cleaned_data['tcp_ports_in'], Port.UDP, Port.OUT) + + if commit: + instance.save() + + return instance diff --git a/machines/views.py b/machines/views.py index 32b04c2e..a35ad79d 100644 --- a/machines/views.py +++ b/machines/views.py @@ -925,6 +925,11 @@ def edit_portlist(request, pk): port_list_instance = get_object_or_404(PortList, pk=pk) port_list = EditPortListForm(request.POST or None, instance=port_list_instance) if port_list.is_valid(): + with transaction.atomic(), reversion.create_revision(): + port_list.save() + reversion.set_user(request.user) + reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in port_list.changed_data)) + messages.success(request, "Liste de ports modifiée") return redirect("/machines/index_portlist/") return form({'machineform' : port_list}, 'machines/machine.html', request) From 6f0e657ae566132b4cf47027fdfd8d866e949b72 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 16:57:51 +0200 Subject: [PATCH 06/21] =?UTF-8?q?Enl=C3=A8ve=20les=20log=20inutilisables.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/machines/views.py b/machines/views.py index a35ad79d..31e9545f 100644 --- a/machines/views.py +++ b/machines/views.py @@ -927,8 +927,6 @@ def edit_portlist(request, pk): if port_list.is_valid(): with transaction.atomic(), reversion.create_revision(): port_list.save() - reversion.set_user(request.user) - reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in port_list.changed_data)) messages.success(request, "Liste de ports modifiée") return redirect("/machines/index_portlist/") return form({'machineform' : port_list}, 'machines/machine.html', request) From a501efeb55f20eb44a225eff041d20f6ecc6dd53 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 17:09:00 +0200 Subject: [PATCH 07/21] Suppression de liste de ports. --- .../templates/machines/index_portlist.html | 4 +--- machines/urls.py | 1 + machines/views.py | 23 ++++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html index 81847af1..b7a9d00d 100644 --- a/machines/templates/machines/index_portlist.html +++ b/machines/templates/machines/index_portlist.html @@ -26,9 +26,7 @@ {% for p in pl.udp_ports_in %}{{p.show_port}}, {%endfor%} {% for p in pl.udp_ports_out %}{{p.show_port}}, {%endfor%} - {%comment%} - {% include 'buttons/suppr.html' href='machines:del-portlist' id=pl.id %} - {%endcomment%} + {% include 'buttons/suppr.html' with href='machines:del-portlist' id=pl.id %} {% include 'buttons/edit.html' with href='machines:edit-portlist' id=pl.id %} diff --git a/machines/urls.py b/machines/urls.py index 29f7668f..bae9535f 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -94,4 +94,5 @@ urlpatterns = [ url(r'^rest/service_servers/$', views.service_servers, name='service-servers'), url(r'index_portlist/$', views.index_portlist, name='index-portlist'), url(r'^edit_portlist/(?P[0-9]+)$', views.edit_portlist, name='edit-portlist'), + url(r'^del_portlist/(?P[0-9]+)$', views.del_portlist, name='del-portlist'), ] diff --git a/machines/views.py b/machines/views.py index 31e9545f..e394fdc1 100644 --- a/machines/views.py +++ b/machines/views.py @@ -922,7 +922,11 @@ def index_portlist(request): @login_required @permission_required('bureau') def edit_portlist(request, pk): - port_list_instance = get_object_or_404(PortList, pk=pk) + try: + port_list_instance = PortList.objects.get(pk=pk) + except PortList.DoesNotExist: + messages.error(request, "Liste de ports inexistante") + return redirect("/machines/index_portlist/") port_list = EditPortListForm(request.POST or None, instance=port_list_instance) if port_list.is_valid(): with transaction.atomic(), reversion.create_revision(): @@ -931,6 +935,23 @@ def edit_portlist(request, pk): return redirect("/machines/index_portlist/") return form({'machineform' : port_list}, 'machines/machine.html', request) +@login_required +@permission_required('bureau') +def del_portlist(request, pk): + try: + port_list_instance = PortList.objects.get(pk=pk) + except PortList.DoesNotExist: + messages.error(request, "Liste de ports inexistante") + return redirect("/machines/index_portlist/") + if port_list_instance.interfaces.all(): + messages.error(request, "Cette liste de ports est utilisée") + return redirect("/machines/index_portlist/") + port_list_instance.delete() + messages.success(request, "La liste de ports a été supprimée") + return redirect("/machines/index_portlist/") + + + """ Framework Rest """ class JSONResponse(HttpResponse): From 2773c76fd617d14f220bd4b0020d3008e6f40596 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 17:11:07 +0200 Subject: [PATCH 08/21] Les cableurs peuvent voir les configurations de ports. --- machines/templates/machines/sidebar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index a0d6948a..e635d69a 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -55,7 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Services (dhcp, dns...) {% endif %} - {% if is_bureau %} + {% if is_cableur %} Configuration de ports From 0209e320410c763178d06d117c4031ac71c58179 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 17:19:42 +0200 Subject: [PATCH 09/21] =?UTF-8?q?Cr=C3=A9ation=20de=20liste=20de=20ports.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 2 ++ machines/templates/machines/index_portlist.html | 2 +- machines/urls.py | 1 + machines/views.py | 12 ++++++++++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/machines/forms.py b/machines/forms.py index dec2cad2..ee84adfc 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -262,6 +262,8 @@ class EditPortListForm(ModelForm): split = r',\s+' ip_range = r'\d+-\d+' + if instance.pk == None: # On ne peut pas créer de ForeignKey sur des objets sans pk + instance.save() def add_port(string, protocole, mode): for p in re.split(split, string): if not p: diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html index b7a9d00d..c21ea30e 100644 --- a/machines/templates/machines/index_portlist.html +++ b/machines/templates/machines/index_portlist.html @@ -6,7 +6,7 @@ {% block content %}

Liste des configurations de ports

-
Ajouter une configuration + Ajouter une configuration diff --git a/machines/urls.py b/machines/urls.py index bae9535f..51cf962e 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -95,4 +95,5 @@ urlpatterns = [ url(r'index_portlist/$', views.index_portlist, name='index-portlist'), url(r'^edit_portlist/(?P[0-9]+)$', views.edit_portlist, name='edit-portlist'), url(r'^del_portlist/(?P[0-9]+)$', views.del_portlist, name='del-portlist'), + url(r'^add_portlist/$', views.add_portlist, name='add-portlist'), ] diff --git a/machines/views.py b/machines/views.py index e394fdc1..9c1ad718 100644 --- a/machines/views.py +++ b/machines/views.py @@ -929,8 +929,7 @@ def edit_portlist(request, pk): return redirect("/machines/index_portlist/") port_list = EditPortListForm(request.POST or None, instance=port_list_instance) if port_list.is_valid(): - with transaction.atomic(), reversion.create_revision(): - port_list.save() + port_list.save() messages.success(request, "Liste de ports modifiée") return redirect("/machines/index_portlist/") return form({'machineform' : port_list}, 'machines/machine.html', request) @@ -950,6 +949,15 @@ def del_portlist(request, pk): messages.success(request, "La liste de ports a été supprimée") return redirect("/machines/index_portlist/") +@login_required +@permission_required('bureau') +def add_portlist(request): + port_list = EditPortListForm(request.POST or None) + if port_list.is_valid(): + port_list.save() + messages.success(request, "Liste de ports créée") + return redirect("/machines/index_portlist/") + return form({'machineform' : port_list}, 'machines/machine.html', request) """ Framework Rest """ From c0a692ea21d8ef4df2cc2d20bc827118cf4cbc19 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 18:02:51 +0200 Subject: [PATCH 10/21] =?UTF-8?q?Nommage=20coh=C3=A9rent.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machines/views.py b/machines/views.py index 9c1ad718..eed0e4c8 100644 --- a/machines/views.py +++ b/machines/views.py @@ -942,7 +942,7 @@ def del_portlist(request, pk): except PortList.DoesNotExist: messages.error(request, "Liste de ports inexistante") return redirect("/machines/index_portlist/") - if port_list_instance.interfaces.all(): + if port_list_instance.interface_set.all(): messages.error(request, "Cette liste de ports est utilisée") return redirect("/machines/index_portlist/") port_list_instance.delete() From b5c6330f5484c6abff0ba3b6ee2a87719d4d4d65 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 21:57:10 +0200 Subject: [PATCH 11/21] =?UTF-8?q?Utilisation=20de=20formset=20pour=20?= =?UTF-8?q?=C3=A9diter=20une=20liste=20de=20ports.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 68 ++---------------- machines/models.py | 5 +- .../templates/machines/edit_portlist.html | 69 +++++++++++++++++++ machines/views.py | 24 +++++-- 4 files changed, 96 insertions(+), 70 deletions(-) create mode 100644 machines/templates/machines/edit_portlist.html diff --git a/machines/forms.py b/machines/forms.py index ee84adfc..863a4d6f 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -59,6 +59,7 @@ class EditInterfaceForm(ModelForm): 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" + self.fields['port_lists'].label = "Configuration des ports" if "machine" in self.fields: self.fields['machine'].queryset = Machine.objects.all().select_related('user') @@ -231,68 +232,13 @@ class VlanForm(ModelForm): class DelVlanForm(Form): vlan = forms.ModelMultipleChoiceField(queryset=Vlan.objects.all(), label="Vlan actuels", widget=forms.CheckboxSelectMultiple) +class EditPortForm(ModelForm): + class Meta: + model = Port + fields = '__all__' + class EditPortListForm(ModelForm): - tcp_ports_in = forms.CharField(required=False, label="Ports TCP (entrée)") - udp_ports_in = forms.CharField(required=False, label="Ports UDP (entrée)") - tcp_ports_out = forms.CharField(required=False, label="Ports TCP (sortie)") - udp_ports_out = forms.CharField(required=False, label="Ports UDP (sortie)") class Meta: model = PortList - fields = ['name'] - - def __init__(self, *args, **kwargs): - super(EditPortListForm, self).__init__(*args, **kwargs) - self.fields['name'].label = "Nom de la liste" - if 'instance' in kwargs.keys(): - p = kwargs['instance'] - self.fields['tcp_ports_in'].initial = ', '.join(map(str, p.tcp_ports_in())) - self.fields['tcp_ports_out'].initial = ', '.join(map(str, p.tcp_ports_out())) - self.fields['udp_ports_in'].initial = ', '.join(map(str, p.udp_ports_in())) - self.fields['udp_ports_out'].initial = ', '.join(map(str, p.udp_ports_out())) - - def save(self, commit=False): - """ - Sauvegarde l'instance. Le commit est obligatoire à cause des ForeignKey. - """ - instance = super(EditPortListForm, self).save(commit=False) - - # Suppression des anciens ports. - for port in instance.port_set.all(): - port.delete() - - split = r',\s+' - ip_range = r'\d+-\d+' - if instance.pk == None: # On ne peut pas créer de ForeignKey sur des objets sans pk - instance.save() - def add_port(string, protocole, mode): - for p in re.split(split, string): - if not p: - continue - if re.match(ip_range, p): - a,b = p.split('-') - a,b = int(a), int(b) - begin,end = min(a,b),max(a,b) - else: - begin = end = int(p.strip()) - port = Port() - port.begin = begin - port.end = end - port.port_list = instance - port.protocole = protocole - port.io = mode - port.save() - - # Ajout des ports TCP en entrée - add_port(self.cleaned_data['tcp_ports_in'], Port.TCP, Port.IN) - # Ajout des ports TCP en sortie - add_port(self.cleaned_data['tcp_ports_out'], Port.TCP, Port.OUT) - # Ajout des ports UDP en entrée - add_port(self.cleaned_data['tcp_ports_in'], Port.UDP, Port.IN) - # Ajout des ports UDP en sortie - add_port(self.cleaned_data['tcp_ports_in'], Port.UDP, Port.OUT) - - if commit: - instance.save() - - return instance + fields = '__all__' diff --git a/machines/models.py b/machines/models.py index 949d9608..7c13e8eb 100644 --- a/machines/models.py +++ b/machines/models.py @@ -223,7 +223,7 @@ 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) - has_public_ip = False + port_lists = models.ManyToManyField('PortList', blank=True) @cached_property def is_active(self): @@ -411,11 +411,10 @@ class Service_link(models.Model): class PortList(models.Model): """Liste des ports ouverts sur une interface.""" - interfaces = models.ManyToManyField('Interface') name = models.CharField(help_text="Nom de la configuration des ports.", max_length=255) def __str__(self): - return ', '.join(map(str, self.port_set.all())) + return self.name def tcp_ports_in(self): return self.port_set.filter(protocole=Port.TCP, io=Port.IN) diff --git a/machines/templates/machines/edit_portlist.html b/machines/templates/machines/edit_portlist.html new file mode 100644 index 00000000..21cc46f2 --- /dev/null +++ b/machines/templates/machines/edit_portlist.html @@ -0,0 +1,69 @@ +{% extends "machines/sidebar.html" %} +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2017 Gabriel Détraz +Copyright © 2017 Goulven Kermarec +Copyright © 2017 Augustin Lemesle + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} + +{% load bootstrap3 %} + +{% block title %}Création et modification de machines{% endblock %} + +{% block content %} +{% bootstrap_form_errors port_list %} + + +
+ {% csrf_token %} + {% bootstrap_form port_list %} + {{ ports.management_form }} +
+ {% for form in ports.forms %} +
+

+ {{ form }} +

+
+ {% endfor %} +
+ +

+ +

+ + {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %} + + +{% endblock %} diff --git a/machines/views.py b/machines/views.py index eed0e4c8..b02d2198 100644 --- a/machines/views.py +++ b/machines/views.py @@ -35,7 +35,7 @@ from django.template import Context, RequestContext, loader from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.db.models import ProtectedError -from django.forms import ValidationError +from django.forms import ValidationError, formset_factory, modelformset_factory from django.db import transaction from django.contrib.auth import authenticate, login from django.views.decorators.csrf import csrf_exempt @@ -48,8 +48,8 @@ from reversion.models import Version import re from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm -from .forms import EditPortListForm -from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, PortList +from .forms import EditPortListForm, EditPortForm +from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, PortList, Port from users.models import User from users.models import all_has_access from preferences.models import GeneralOption, OptionalMachine @@ -928,11 +928,23 @@ def edit_portlist(request, pk): messages.error(request, "Liste de ports inexistante") return redirect("/machines/index_portlist/") port_list = EditPortListForm(request.POST or None, instance=port_list_instance) - if port_list.is_valid(): - port_list.save() + port_formset = modelformset_factory( + Port, + fields=('begin','end','protocole','io'), + extra=0, + can_delete=True + )(request.POST or None, queryset=port_list_instance.port_set.all()) + if port_list.is_valid() and port_formset.is_valid(): + pl = port_list.save() + instances = port_formset.save(commit=False) + for to_delete in port_formset.deleted_objects: + to_delete.delete() + for port in instances: + port.port_list = pl + port.save() messages.success(request, "Liste de ports modifiée") return redirect("/machines/index_portlist/") - return form({'machineform' : port_list}, 'machines/machine.html', request) + return form({'port_list' : port_list, 'ports' : port_formset}, 'machines/edit_portlist.html', request) @login_required @permission_required('bureau') From b95c19db2d61ea96f43f74f91506a1b1fd287410 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 22:04:37 +0200 Subject: [PATCH 12/21] =?UTF-8?q?Cr=C3=A9ation=20de=20liste=20de=20ports?= =?UTF-8?q?=20via=20formset.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/views.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/machines/views.py b/machines/views.py index b02d2198..36db72cd 100644 --- a/machines/views.py +++ b/machines/views.py @@ -35,7 +35,7 @@ from django.template import Context, RequestContext, loader from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.db.models import ProtectedError -from django.forms import ValidationError, formset_factory, modelformset_factory +from django.forms import ValidationError, modelformset_factory from django.db import transaction from django.contrib.auth import authenticate, login from django.views.decorators.csrf import csrf_exempt @@ -964,6 +964,24 @@ def del_portlist(request, pk): @login_required @permission_required('bureau') def add_portlist(request): + port_list = EditPortListForm(request.POST or None) + port_formset = modelformset_factory( + Port, + fields=('begin','end','protocole','io'), + extra=1, + can_delete=True + )(request.POST or None, queryset=Port.objects.none()) + if port_list.is_valid() and port_formset.is_valid(): + pl = port_list.save() + instances = port_formset.save(commit=False) + for to_delete in port_formset.deleted_objects: + to_delete.delete() + for port in instances: + port.port_list = pl + port.save() + messages.success(request, "Liste de ports créée") + return redirect("/machines/index_portlist/") + return form({'port_list' : port_list, 'ports' : port_formset}, 'machines/edit_portlist.html', request) port_list = EditPortListForm(request.POST or None) if port_list.is_valid(): port_list.save() From 9fcecad007ee7acf3f9b5fe3b0a43bb575c04b2e Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 1 Oct 2017 23:13:10 +0200 Subject: [PATCH 13/21] Ne permet pas de sauvegarder de liste de ports vides. --- machines/views.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/machines/views.py b/machines/views.py index 36db72cd..54828999 100644 --- a/machines/views.py +++ b/machines/views.py @@ -932,7 +932,9 @@ def edit_portlist(request, pk): Port, fields=('begin','end','protocole','io'), extra=0, - can_delete=True + can_delete=True, + min_num=1, + validate_min=True, )(request.POST or None, queryset=port_list_instance.port_set.all()) if port_list.is_valid() and port_formset.is_valid(): pl = port_list.save() @@ -968,8 +970,10 @@ def add_portlist(request): port_formset = modelformset_factory( Port, fields=('begin','end','protocole','io'), - extra=1, - can_delete=True + extra=0, + can_delete=True, + min_num=1, + validate_min=True, )(request.POST or None, queryset=Port.objects.none()) if port_list.is_valid() and port_formset.is_valid(): pl = port_list.save() From f56ca250ba7ba51927fd28ba69919d587bac8159 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Mon, 2 Oct 2017 00:08:07 +0200 Subject: [PATCH 14/21] =?UTF-8?q?Affectation=20de=20configuration=20de=20p?= =?UTF-8?q?orts=20=C3=A0=20une=20interface.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 10 ++++---- .../migrations/0061_auto_20171001_1727.py | 24 +++++++++++++++++++ machines/models.py | 3 +++ machines/templates/machines/aff_machines.html | 5 ++++ machines/urls.py | 2 ++ machines/views.py | 16 ++++++++++++- 6 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 machines/migrations/0061_auto_20171001_1727.py diff --git a/machines/forms.py b/machines/forms.py index 863a4d6f..34d9652f 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -52,14 +52,14 @@ class BaseEditMachineForm(EditMachineForm): class EditInterfaceForm(ModelForm): class Meta: model = Interface - fields = '__all__' + # fields = '__all__' + exclude = ['port_lists'] def __init__(self, *args, **kwargs): super(EditInterfaceForm, self).__init__(*args, **kwargs) 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" - self.fields['port_lists'].label = "Configuration des ports" if "machine" in self.fields: self.fields['machine'].queryset = Machine.objects.all().select_related('user') @@ -232,10 +232,10 @@ class VlanForm(ModelForm): class DelVlanForm(Form): vlan = forms.ModelMultipleChoiceField(queryset=Vlan.objects.all(), label="Vlan actuels", widget=forms.CheckboxSelectMultiple) -class EditPortForm(ModelForm): +class EditPortConfigForm(ModelForm): class Meta: - model = Port - fields = '__all__' + model = Interface + fields = ['port_lists'] class EditPortListForm(ModelForm): class Meta: diff --git a/machines/migrations/0061_auto_20171001_1727.py b/machines/migrations/0061_auto_20171001_1727.py new file mode 100644 index 00000000..661f9fd3 --- /dev/null +++ b/machines/migrations/0061_auto_20171001_1727.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-10-01 15:27 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0060_port_io'), + ] + + operations = [ + migrations.RemoveField( + model_name='portlist', + name='interfaces', + ), + migrations.AddField( + model_name='interface', + name='port_lists', + field=models.ManyToManyField(to='machines.PortList'), + ), + ] diff --git a/machines/models.py b/machines/models.py index 7c13e8eb..bf5a774d 100644 --- a/machines/models.py +++ b/machines/models.py @@ -279,6 +279,9 @@ class Interface(models.Model): domain = None return str(domain) + def has_private_ip(self): + return IPAddress(str(self.ipv4)).is_private() + class Domain(models.Model): PRETTY_NAME = "Domaine dns" diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index a09d8868..c4a2dd56 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -91,6 +91,11 @@ with this program; if not, write to the Free Software Foundation, Inc., Gerer les alias +
  • + + Gerer la configuration des ports + +
  • Historique diff --git a/machines/urls.py b/machines/urls.py index 51cf962e..62576a4e 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -96,4 +96,6 @@ urlpatterns = [ url(r'^edit_portlist/(?P[0-9]+)$', views.edit_portlist, name='edit-portlist'), url(r'^del_portlist/(?P[0-9]+)$', views.del_portlist, name='del-portlist'), url(r'^add_portlist/$', views.add_portlist, name='add-portlist'), + url(r'^port_config/(?P[0-9]+)$', views.configure_ports, name='port-config'), + ] diff --git a/machines/views.py b/machines/views.py index 54828999..9aaf90e7 100644 --- a/machines/views.py +++ b/machines/views.py @@ -48,7 +48,7 @@ from reversion.models import Version import re from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm -from .forms import EditPortListForm, EditPortForm +from .forms import EditPortListForm, EditPortConfigForm from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, PortList, Port from users.models import User from users.models import all_has_access @@ -993,6 +993,20 @@ def add_portlist(request): return redirect("/machines/index_portlist/") return form({'machineform' : port_list}, 'machines/machine.html', request) +@login_required +@permission_required('cableur') +def configure_ports(request, pk): + try: + interface_instance = Interface.objects.get(pk=pk) + except Interface.DoesNotExist: + messages.error(request, u"Interface inexistante" ) + return redirect("/machines") + interface = EditPortConfigForm(request.POST or None, instance=interface_instance) + if interface.is_valid(): + interface.save() + messages.success(request, "Configuration des ports mise à jour.") + return redirect("/machines/") + return form({'interfaceform' : interface}, 'machines/machine.html', request) """ Framework Rest """ From b40f09cefbc0acedef99a79ef0ea29d968e71aca Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Mon, 2 Oct 2017 01:52:14 +0200 Subject: [PATCH 15/21] Affichage des machines par profil de port --- .../templates/machines/index_portlist.html | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html index c21ea30e..04ac66d4 100644 --- a/machines/templates/machines/index_portlist.html +++ b/machines/templates/machines/index_portlist.html @@ -15,6 +15,7 @@
  • + @@ -25,6 +26,23 @@ + + @@ -42,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., + - + @@ -74,7 +74,9 @@ with this program; if not, write to the Free Software Foundation, Inc., - + - + + +
    TCP (sortie) UDP (entrée) UDP (sortie)Machines
    {% for p in pl.tcp_ports_out %}{{p.show_port}}, {%endfor%} {% for p in pl.udp_ports_in %}{{p.show_port}}, {%endfor%} {% for p in pl.udp_ports_out %}{{p.show_port}}, {%endfor%} + {% if pl.interface_set.all %} + + {% endif %} {% include 'buttons/suppr.html' with href='machines:del-portlist' id=pl.id %} {% include 'buttons/edit.html' with href='machines:edit-portlist' id=pl.id %} From 98cc1808da8077b674a2d46deb144ddfa668b0d1 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Mon, 2 Oct 2017 04:19:07 +0200 Subject: [PATCH 16/21] Renomage des tables, ecriture des admin et fioritures --- machines/admin.py | 14 +++++++++- machines/forms.py | 8 +++--- ...928_1711.py => 0058_auto_20171002_0350.py} | 18 ++++++++---- machines/migrations/0059_port_protocole.py | 20 ------------- machines/migrations/0060_port_io.py | 20 ------------- .../migrations/0061_auto_20171001_1727.py | 24 ---------------- machines/models.py | 26 +++++++++++------ machines/views.py | 28 +++++++++---------- 8 files changed, 60 insertions(+), 98 deletions(-) rename machines/migrations/{0058_auto_20170928_1711.py => 0058_auto_20171002_0350.py} (61%) delete mode 100644 machines/migrations/0059_port_protocole.py delete mode 100644 machines/migrations/0060_port_io.py delete mode 100644 machines/migrations/0061_auto_20171001_1727.py diff --git a/machines/admin.py b/machines/admin.py index 5fe4c49b..49b02a7e 100644 --- a/machines/admin.py +++ b/machines/admin.py @@ -26,7 +26,9 @@ from __future__ import unicode_literals from django.contrib import admin from reversion.admin import VersionAdmin -from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Vlan, Text, Nas, Service +from .models import IpType, Machine, MachineType, Domain, IpList, Interface +from .models import Extension, Mx, Ns, Vlan, Text, Nas, Service, OuverturePort +from .models import OuverturePortList class MachineAdmin(VersionAdmin): pass @@ -58,6 +60,12 @@ class NasAdmin(VersionAdmin): class IpListAdmin(VersionAdmin): pass +class OuverturePortAdmin(VersionAdmin): + pass + +class OuverturePortListAdmin(VersionAdmin): + pass + class InterfaceAdmin(VersionAdmin): list_display = ('machine','type','mac_address','ipv4','details') @@ -80,3 +88,7 @@ admin.site.register(Domain, DomainAdmin) admin.site.register(Service, ServiceAdmin) admin.site.register(Vlan, VlanAdmin) admin.site.register(Nas, NasAdmin) +admin.site.register(OuverturePort, OuverturePortAdmin) +admin.site.register(OuverturePortList, OuverturePortListAdmin) + + diff --git a/machines/forms.py b/machines/forms.py index 34d9652f..c29af9dd 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -26,7 +26,7 @@ import re from django.forms import ModelForm, Form, ValidationError from django import forms -from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType, PortList, Port +from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType, OuverturePortList, OuverturePort from django.db.models import Q from django.core.validators import validate_email @@ -232,13 +232,13 @@ class VlanForm(ModelForm): class DelVlanForm(Form): vlan = forms.ModelMultipleChoiceField(queryset=Vlan.objects.all(), label="Vlan actuels", widget=forms.CheckboxSelectMultiple) -class EditPortConfigForm(ModelForm): +class EditOuverturePortConfigForm(ModelForm): class Meta: model = Interface fields = ['port_lists'] -class EditPortListForm(ModelForm): +class EditOuverturePortListForm(ModelForm): class Meta: - model = PortList + model = OuverturePortList fields = '__all__' diff --git a/machines/migrations/0058_auto_20170928_1711.py b/machines/migrations/0058_auto_20171002_0350.py similarity index 61% rename from machines/migrations/0058_auto_20170928_1711.py rename to machines/migrations/0058_auto_20171002_0350.py index 41224de1..bc6b2508 100644 --- a/machines/migrations/0058_auto_20170928_1711.py +++ b/machines/migrations/0058_auto_20171002_0350.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2017-09-28 15:11 +# Generated by Django 1.10.7 on 2017-10-02 01:50 from __future__ import unicode_literals from django.db import migrations, models @@ -14,24 +14,30 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Port', + name='OuverturePort', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('begin', models.IntegerField()), ('end', models.IntegerField()), + ('protocole', models.CharField(choices=[('T', 'TCP'), ('U', 'UDP')], default='T', max_length=1)), + ('io', models.CharField(choices=[('I', 'IN'), ('O', 'OUT')], default='O', max_length=1)), ], ), migrations.CreateModel( - name='PortList', + name='OuverturePortList', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='Nom de la configuration des ports.', max_length=255)), - ('interfaces', models.ManyToManyField(to='machines.Interface')), ], ), migrations.AddField( - model_name='port', + model_name='ouvertureport', name='port_list', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.PortList'), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.OuverturePortList'), + ), + migrations.AddField( + model_name='interface', + name='port_lists', + field=models.ManyToManyField(blank=True, to='machines.OuverturePortList'), ), ] diff --git a/machines/migrations/0059_port_protocole.py b/machines/migrations/0059_port_protocole.py deleted file mode 100644 index fc43bdb0..00000000 --- a/machines/migrations/0059_port_protocole.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2017-09-28 16:03 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('machines', '0058_auto_20170928_1711'), - ] - - operations = [ - migrations.AddField( - model_name='port', - name='protocole', - field=models.CharField(choices=[('T', 'TCP'), ('U', 'UDP')], default='T', max_length=1), - ), - ] diff --git a/machines/migrations/0060_port_io.py b/machines/migrations/0060_port_io.py deleted file mode 100644 index 0d890b56..00000000 --- a/machines/migrations/0060_port_io.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2017-10-01 09:30 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('machines', '0059_port_protocole'), - ] - - operations = [ - migrations.AddField( - model_name='port', - name='io', - field=models.CharField(choices=[('I', 'IN'), ('O', 'OUT')], default='O', max_length=1), - ), - ] diff --git a/machines/migrations/0061_auto_20171001_1727.py b/machines/migrations/0061_auto_20171001_1727.py deleted file mode 100644 index 661f9fd3..00000000 --- a/machines/migrations/0061_auto_20171001_1727.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2017-10-01 15:27 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('machines', '0060_port_io'), - ] - - operations = [ - migrations.RemoveField( - model_name='portlist', - name='interfaces', - ), - migrations.AddField( - model_name='interface', - name='port_lists', - field=models.ManyToManyField(to='machines.PortList'), - ), - ] diff --git a/machines/models.py b/machines/models.py index bf5a774d..0313470d 100644 --- a/machines/models.py +++ b/machines/models.py @@ -223,7 +223,7 @@ 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) - port_lists = models.ManyToManyField('PortList', blank=True) + port_lists = models.ManyToManyField('OuverturePortList', blank=True) @cached_property def is_active(self): @@ -280,8 +280,13 @@ class Interface(models.Model): return str(domain) def has_private_ip(self): - return IPAddress(str(self.ipv4)).is_private() + if hasattr(self, 'ipv4'): + return IPAddress(str(self.ipv4)).is_private() + else: + return False + def may_have_port_open(self): + return hasattr(self, 'ipv4') and self.has_private_ip() class Domain(models.Model): PRETTY_NAME = "Domaine dns" @@ -412,7 +417,7 @@ class Service_link(models.Model): return str(self.server) + " " + str(self.service) -class PortList(models.Model): +class OuverturePortList(models.Model): """Liste des ports ouverts sur une interface.""" name = models.CharField(help_text="Nom de la configuration des ports.", max_length=255) @@ -420,19 +425,19 @@ class PortList(models.Model): return self.name def tcp_ports_in(self): - return self.port_set.filter(protocole=Port.TCP, io=Port.IN) + return self.ouvertureport_set.filter(protocole=OuverturePort.TCP, io=OuverturePort.IN) def udp_ports_in(self): - return self.port_set.filter(protocole=Port.UDP, io=Port.IN) + return self.ouvertureport_set.filter(protocole=OuverturePort.UDP, io=OuverturePort.IN) def tcp_ports_out(self): - return self.port_set.filter(protocole=Port.TCP, io=Port.OUT) + return self.ouvertureport_set.filter(protocole=OuverturePort.TCP, io=OuverturePort.OUT) def udp_ports_out(self): - return self.port_set.filter(protocole=Port.UDP, io=Port.OUT) + return self.ouvertureport_set.filter(protocole=OuverturePort.UDP, io=OuverturePort.OUT) -class Port(models.Model): +class OuverturePort(models.Model): """ Représente un simple port ou une plage de ports. @@ -445,7 +450,7 @@ class Port(models.Model): OUT = 'O' begin = models.IntegerField() end = models.IntegerField() - port_list = models.ForeignKey('PortList', on_delete=models.CASCADE) + port_list = models.ForeignKey('OuverturePortList', on_delete=models.CASCADE) protocole = models.CharField( max_length=1, choices=( @@ -492,6 +497,9 @@ def interface_post_save(sender, **kwargs): interface = kwargs['instance'] user = interface.machine.user user.ldap_sync(base=False, access_refresh=False, mac_refresh=True) + if interface.may_have_port_open() and interface.port_lists.all(): + interface.port_lists.clear() + # Regen services regen('dhcp') regen('mac_ip_list') diff --git a/machines/views.py b/machines/views.py index 9aaf90e7..8a01d813 100644 --- a/machines/views.py +++ b/machines/views.py @@ -48,8 +48,8 @@ from reversion.models import Version import re from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm -from .forms import EditPortListForm, EditPortConfigForm -from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, PortList, Port +from .forms import EditOuverturePortListForm, EditOuverturePortConfigForm +from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, OuverturePortList, OuverturePort from users.models import User from users.models import all_has_access from preferences.models import GeneralOption, OptionalMachine @@ -916,20 +916,20 @@ def history(request, object, id): @login_required @permission_required('cableur') def index_portlist(request): - port_list = PortList.objects.all().order_by('name') + port_list = OuverturePortList.objects.all().order_by('name') return render(request, "machines/index_portlist.html", {'port_list':port_list}) @login_required @permission_required('bureau') def edit_portlist(request, pk): try: - port_list_instance = PortList.objects.get(pk=pk) - except PortList.DoesNotExist: + port_list_instance = OuverturePortList.objects.get(pk=pk) + except OuverturePortList.DoesNotExist: messages.error(request, "Liste de ports inexistante") return redirect("/machines/index_portlist/") - port_list = EditPortListForm(request.POST or None, instance=port_list_instance) + port_list = EditOuverturePortListForm(request.POST or None, instance=port_list_instance) port_formset = modelformset_factory( - Port, + OuverturePort, fields=('begin','end','protocole','io'), extra=0, can_delete=True, @@ -952,8 +952,8 @@ def edit_portlist(request, pk): @permission_required('bureau') def del_portlist(request, pk): try: - port_list_instance = PortList.objects.get(pk=pk) - except PortList.DoesNotExist: + port_list_instance = OuverturePortList.objects.get(pk=pk) + except OuverturePortList.DoesNotExist: messages.error(request, "Liste de ports inexistante") return redirect("/machines/index_portlist/") if port_list_instance.interface_set.all(): @@ -966,15 +966,15 @@ def del_portlist(request, pk): @login_required @permission_required('bureau') def add_portlist(request): - port_list = EditPortListForm(request.POST or None) + port_list = EditOuverturePortListForm(request.POST or None) port_formset = modelformset_factory( - Port, + OuverturePort, fields=('begin','end','protocole','io'), extra=0, can_delete=True, min_num=1, validate_min=True, - )(request.POST or None, queryset=Port.objects.none()) + )(request.POST or None, queryset=OuverturePort.objects.none()) if port_list.is_valid() and port_formset.is_valid(): pl = port_list.save() instances = port_formset.save(commit=False) @@ -986,7 +986,7 @@ def add_portlist(request): messages.success(request, "Liste de ports créée") return redirect("/machines/index_portlist/") return form({'port_list' : port_list, 'ports' : port_formset}, 'machines/edit_portlist.html', request) - port_list = EditPortListForm(request.POST or None) + port_list = EditOuverturePortListForm(request.POST or None) if port_list.is_valid(): port_list.save() messages.success(request, "Liste de ports créée") @@ -1001,7 +1001,7 @@ def configure_ports(request, pk): except Interface.DoesNotExist: messages.error(request, u"Interface inexistante" ) return redirect("/machines") - interface = EditPortConfigForm(request.POST or None, instance=interface_instance) + interface = EditOuverturePortConfigForm(request.POST or None, instance=interface_instance) if interface.is_valid(): interface.save() messages.success(request, "Configuration des ports mise à jour.") From 3147066a852e7868aea606441ff5653fc9f4b622 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 Oct 2017 04:54:40 +0200 Subject: [PATCH 17/21] =?UTF-8?q?L'affichage=20et=20l'acc=C3=A8s=20au=20me?= =?UTF-8?q?nu=20port=20sont=20possible=20que=20si=20ip=20publique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/models.py | 6 +++--- machines/templates/machines/aff_machines.html | 2 ++ machines/views.py | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/machines/models.py b/machines/models.py index 0313470d..cb859141 100644 --- a/machines/models.py +++ b/machines/models.py @@ -280,13 +280,13 @@ class Interface(models.Model): return str(domain) def has_private_ip(self): - if hasattr(self, 'ipv4'): + if self.ipv4: return IPAddress(str(self.ipv4)).is_private() else: return False def may_have_port_open(self): - return hasattr(self, 'ipv4') and self.has_private_ip() + return self.ipv4 and not self.has_private_ip() class Domain(models.Model): PRETTY_NAME = "Domaine dns" @@ -497,7 +497,7 @@ def interface_post_save(sender, **kwargs): interface = kwargs['instance'] user = interface.machine.user user.ldap_sync(base=False, access_refresh=False, mac_refresh=True) - if interface.may_have_port_open() and interface.port_lists.all(): + if not interface.may_have_port_open() and interface.port_lists.all(): interface.port_lists.clear() # Regen services regen('dhcp') diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index c4a2dd56..6cf306f7 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -91,11 +91,13 @@ with this program; if not, write to the Free Software Foundation, Inc., Gerer les alias + {% if interface.may_have_port_open %}
  • Gerer la configuration des ports
  • + {% endif %}
  • Historique diff --git a/machines/views.py b/machines/views.py index 8a01d813..8200843c 100644 --- a/machines/views.py +++ b/machines/views.py @@ -1001,6 +1001,9 @@ def configure_ports(request, pk): except Interface.DoesNotExist: messages.error(request, u"Interface inexistante" ) return redirect("/machines") + if not interface_instance.may_have_port_open(): + messages.error(request, "L'ip de cette interface n'est pas publique ou non assignée") + return redirect("/machines") interface = EditOuverturePortConfigForm(request.POST or None, instance=interface_instance) if interface.is_valid(): interface.save() From 6d398f0a75c8987b66ab8b822a7ee25f82917b81 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Mon, 2 Oct 2017 05:11:50 +0200 Subject: [PATCH 18/21] Bug fix --- machines/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machines/views.py b/machines/views.py index 8200843c..7dc4a3ca 100644 --- a/machines/views.py +++ b/machines/views.py @@ -935,7 +935,7 @@ def edit_portlist(request, pk): can_delete=True, min_num=1, validate_min=True, - )(request.POST or None, queryset=port_list_instance.port_set.all()) + )(request.POST or None, queryset=port_list_instance.ouvertureport_set.all()) if port_list.is_valid() and port_formset.is_valid(): pl = port_list.save() instances = port_formset.save(commit=False) From 2111cb63dd0b38519090074d03c6d977167cff82 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Tue, 3 Oct 2017 02:36:39 +0200 Subject: [PATCH 19/21] Attribut ipv6 sur les interfaces --- machines/forms.py | 4 ++-- machines/migrations/0059_iptype_prefix_v6.py | 20 +++++++++++++++++++ machines/models.py | 17 +++++++++++++++- machines/templates/machines/aff_iptype.html | 2 ++ machines/templates/machines/aff_machines.html | 6 ++++-- .../migrations/0020_optionalmachine_ipv6.py | 20 +++++++++++++++++++ preferences/models.py | 1 + .../preferences/display_preferences.html | 4 +++- re2o/context_processors.py | 4 +++- 9 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 machines/migrations/0059_iptype_prefix_v6.py create mode 100644 preferences/migrations/0020_optionalmachine_ipv6.py diff --git a/machines/forms.py b/machines/forms.py index c29af9dd..8321db8a 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -142,7 +142,7 @@ class DelMachineTypeForm(Form): class IpTypeForm(ModelForm): class Meta: model = IpType - fields = ['type','extension','need_infra','domaine_ip_start','domaine_ip_stop', 'vlan'] + fields = ['type','extension','need_infra','domaine_ip_start','domaine_ip_stop', 'prefix_v6', 'vlan'] def __init__(self, *args, **kwargs): @@ -151,7 +151,7 @@ class IpTypeForm(ModelForm): class EditIpTypeForm(IpTypeForm): class Meta(IpTypeForm.Meta): - fields = ['extension','type','need_infra', 'vlan'] + fields = ['extension','type','need_infra', 'prefix_v6', 'vlan'] class DelIpTypeForm(Form): iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple) diff --git a/machines/migrations/0059_iptype_prefix_v6.py b/machines/migrations/0059_iptype_prefix_v6.py new file mode 100644 index 00000000..464fc5e6 --- /dev/null +++ b/machines/migrations/0059_iptype_prefix_v6.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-10-02 16:33 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0058_auto_20171002_0350'), + ] + + operations = [ + migrations.AddField( + model_name='iptype', + name='prefix_v6', + field=models.GenericIPAddressField(blank=True, null=True, protocol='IPv6'), + ), + ] diff --git a/machines/models.py b/machines/models.py index cb859141..8e7b1c3c 100644 --- a/machines/models.py +++ b/machines/models.py @@ -70,6 +70,7 @@ class IpType(models.Model): need_infra = models.BooleanField(default=False) domaine_ip_start = models.GenericIPAddressField(protocol='IPv4') domaine_ip_stop = models.GenericIPAddressField(protocol='IPv4') + prefix_v6 = models.GenericIPAddressField(protocol='IPv6', null=True, blank=True) vlan = models.ForeignKey('Vlan', on_delete=models.PROTECT, blank=True, null=True) @cached_property @@ -122,6 +123,9 @@ class IpType(models.Model): for element in IpType.objects.all().exclude(pk=self.pk): if not self.ip_set.isdisjoint(element.ip_set): raise ValidationError("Le range indiqué n'est pas disjoint des ranges existants") + # On formate le prefix v6 + if self.prefix_v6: + self.prefix_v6 = str(IPNetwork(self.prefix_v6 + '/64').network) return def save(self, *args, **kwargs): @@ -218,7 +222,6 @@ class Interface(models.Model): PRETTY_NAME = "Interface" ipv4 = models.OneToOneField('IpList', on_delete=models.PROTECT, blank=True, null=True) - #ipv6 = models.GenericIPAddressField(protocol='IPv6', null=True) mac_address = MACAddressField(integer=False, unique=True) machine = models.ForeignKey('Machine', on_delete=models.CASCADE) type = models.ForeignKey('MachineType', on_delete=models.PROTECT) @@ -232,6 +235,18 @@ class Interface(models.Model): user = self.machine.user return machine.active and user.has_access() + + @cached_property + def ipv6_object(self): + if self.type.ip_type.prefix_v6: + return EUI(self.mac_address).ipv6(IPNetwork(self.type.ip_type.prefix_v6).network) + else: + return None + + @cached_property + def ipv6(self): + return str(self.ipv6_object) + def mac_bare(self): return str(EUI(self.mac_address, dialect=mac_bare)).lower() diff --git a/machines/templates/machines/aff_iptype.html b/machines/templates/machines/aff_iptype.html index 46318c83..aafc4c1d 100644 --- a/machines/templates/machines/aff_iptype.html +++ b/machines/templates/machines/aff_iptype.html @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
  • Nécessite l'autorisation infra Début FinPréfixe v6 Sur vlan {{ type.need_infra }} {{ type.domaine_ip_start }} {{ type.domaine_ip_stop }}{{ type.prefix_v6 }} {{ type.vlan }} {% if is_infra %} diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index 6cf306f7..b9c8c9e9 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Nom dns Type MacIpv4IP
    {{ interface.type }} {{ interface.mac_address }}{{ interface.ipv4 }}{{ interface.ipv4 }} + {{ interface.ipv6 }} +
    Alias dns autorisé par utilisateur {{ machineoptions.max_lambdauser_aliases }}
    Support de l'ipv6{{ machineoptions.ipv6 }}

    Préférences topologie

    {% if is_bureau %} diff --git a/re2o/context_processors.py b/re2o/context_processors.py index dd39b04b..ed4769b5 100644 --- a/re2o/context_processors.py +++ b/re2o/context_processors.py @@ -23,10 +23,11 @@ from __future__ import unicode_literals from machines.models import Interface, Machine -from preferences.models import GeneralOption +from preferences.models import GeneralOption, OptionalMachine def context_user(request): general_options, created = GeneralOption.objects.get_or_create() + machine_options, created = OptionalMachine.objects.get_or_create() user = request.user if user.is_authenticated(): interfaces = user.user_interfaces() @@ -54,4 +55,5 @@ def context_user(request): 'is_admin' : is_admin, 'interfaces': interfaces, 'site_name': general_options.site_name, + 'ipv6_enabled' : machine_options.ipv6, } From 4269ed74bc684cd8651857bb88b9d9e5e19dca6c Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Tue, 3 Oct 2017 04:13:48 +0200 Subject: [PATCH 20/21] =?UTF-8?q?Affichage=20que=20si=20ipv6=20activ=C3=A9?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/templates/machines/aff_machines.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index b9c8c9e9..c22de7c9 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -75,7 +75,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ interface.type }} {{ interface.mac_address }} {{ interface.ipv4 }} + {% if ipv6_enabled %} {{ interface.ipv6 }} + {% endif %}