From 5d553027155d3243913cfcb96455c6e02de27abd Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 80ac47b4e241776077692bcef0c6951357299a03 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 4716d7f34322834df30997f2041abcdfa3be19e4 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 cf9db8f1d1fbf751f63020628b67e087bef14066 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 60e42d699338002c4b93bef503364865bdad7d07 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 9ae9a840be1355808d60c80191c45a75db09b7e7 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 4e2f795e77d4761a3240682b4bfe1c2c1a288f54 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 71d9f1c382cb63a2435b6c9498b30ff62aff2d61 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 779c2be2de928f1353761087c411331b76e72af5 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 a00ad6c5908d9722a654ec79f518522c41b9ed40 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 2b08be8931812dc8aa8e36ca5c442554bc91c270 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 9f3e9b5509e3a3eea2cd4a36cea5c59511cc3ca7 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 ad67b9cbd60e4179e5f1566d1cb92fa04c29f642 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 b57fed742318bfa76abacd6bcb58670401441cd8 Mon Sep 17 00:00:00 2001 From: LEVY-FALK Hugo 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 5f511eaf3fca4991738a53fd964b2a67c36fe79e 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 c459d3f45c5d2fc4dc02b9f18883e0d997a842d7 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 28a29df0549ec3c85f8c55487f7964086ff5c434 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 12fe768754ceba0f8595d85addf6526176721de9 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 5c9c9c3a29ad1d872c1f644fb078183049da944a 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 abbceb6abc5b65e831f54d11aa67e71ec8963fde 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 %}