From 6a50888e405631b3c79ead2ac569e4001c4cf77c Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 26 Aug 2017 15:10:18 +0200 Subject: [PATCH] Omnibus : ajout du suport de la liste vlan + corrections mineures --- cotisations/models.py | 2 +- freeradius_utils/authenticate_filaire.py | 7 +- machines/admin.py | 19 +++--- machines/forms.py | 16 ++++- machines/migrations/0049_vlan.py | 24 +++++++ .../migrations/0050_auto_20170826_0022.py | 20 ++++++ machines/migrations/0051_iptype_vlan.py | 21 ++++++ machines/models.py | 16 ++++- machines/templates/machines/aff_iptype.html | 2 + machines/templates/machines/aff_vlan.html | 50 +++++++++++++++ machines/templates/machines/index_vlan.html | 39 +++++++++++ machines/templates/machines/sidebar.html | 4 ++ machines/urls.py | 5 ++ machines/views.py | 64 ++++++++++++++++++- preferences/admin.py | 7 +- preferences/forms.py | 11 +++- .../migrations/0010_auto_20170825_0459.py | 40 ++++++++++++ .../migrations/0011_auto_20170825_2307.py | 29 +++++++++ preferences/models.py | 6 +- .../preferences/display_preferences.html | 17 +++++ preferences/urls.py | 1 + preferences/views.py | 5 +- re2o/settings_local.example.py | 9 --- topologie/models.py | 4 +- users/models.py | 6 +- 25 files changed, 386 insertions(+), 38 deletions(-) create mode 100644 machines/migrations/0049_vlan.py create mode 100644 machines/migrations/0050_auto_20170826_0022.py create mode 100644 machines/migrations/0051_iptype_vlan.py create mode 100644 machines/templates/machines/aff_vlan.html create mode 100644 machines/templates/machines/index_vlan.html create mode 100644 preferences/migrations/0010_auto_20170825_0459.py create mode 100644 preferences/migrations/0011_auto_20170825_2307.py diff --git a/cotisations/models.py b/cotisations/models.py index 692ff3a2..60e8672e 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -49,7 +49,7 @@ class Facture(models.Model): return Vente.objects.filter(facture=self).aggregate(total=models.Sum(models.F('prix')*models.F('number'), output_field=models.FloatField()))['total'] def name(self): - name = ' - '.join(vente.name for vente in Vente.objects.filter(facture=self)) + name = ' - '.join(Vente.objects.filter(facture=self).values_list('name', flat=True)) return name def __str__(self): diff --git a/freeradius_utils/authenticate_filaire.py b/freeradius_utils/authenticate_filaire.py index 40c38ef2..1fe82209 100755 --- a/freeradius_utils/authenticate_filaire.py +++ b/freeradius_utils/authenticate_filaire.py @@ -40,11 +40,12 @@ from django.db.models import Q from machines.models import Interface, IpList, Domain from topologie.models import Room, Port, Switch from users.models import User +from preferences.models import OptionalTopologie -from re2o.settings import RADIUS_VLAN_DECISION +options, created = OptionalTopologie.objects.get_or_create() +VLAN_NOK = options.vlan_decision_nok.vlan_id +VLAN_OK = options.vlan_decision_ok.vlan_id -VLAN_NOK = RADIUS_VLAN_DECISION['VLAN_NOK'] -VLAN_OK = RADIUS_VLAN_DECISION['VLAN_OK'] def decide_vlan(switch_id, port_number, mac_address): # Get port from switch and port number diff --git a/machines/admin.py b/machines/admin.py index 147fca0f..c9559fe5 100644 --- a/machines/admin.py +++ b/machines/admin.py @@ -23,29 +23,31 @@ from django.contrib import admin from reversion.admin import VersionAdmin -from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Service +from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Vlan, Service class MachineAdmin(VersionAdmin): - list_display = ('user','name','active') + pass class IpTypeAdmin(VersionAdmin): - list_display = ('type','extension','need_infra','domaine_ip','domaine_range') + pass class MachineTypeAdmin(VersionAdmin): - list_display = ('type','ip_type') + pass +class VlanAdmin(VersionAdmin): + pass class ExtensionAdmin(VersionAdmin): - list_display = ('name','origin') + pass class MxAdmin(VersionAdmin): - list_display = ('zone', 'priority', 'name') + pass class NsAdmin(VersionAdmin): - list_display = ('zone', 'ns') + pass class IpListAdmin(VersionAdmin): - list_display = ('ipv4','ip_type') + pass class InterfaceAdmin(VersionAdmin): list_display = ('machine','type','mac_address','ipv4','details') @@ -66,3 +68,4 @@ admin.site.register(IpList, IpListAdmin) admin.site.register(Interface, InterfaceAdmin) admin.site.register(Domain, DomainAdmin) admin.site.register(Service, ServiceAdmin) +admin.site.register(Vlan, VlanAdmin) diff --git a/machines/forms.py b/machines/forms.py index 64f4f3af..3512e277 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -22,7 +22,7 @@ from django.forms import ModelForm, Form, ValidationError from django import forms -from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Service, IpType +from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Service, Vlan, IpType from django.db.models import Q from django.core.validators import validate_email @@ -143,7 +143,7 @@ class DelMachineTypeForm(Form): class IpTypeForm(ModelForm): class Meta: model = IpType - fields = ['type','extension','need_infra','domaine_ip','domaine_range'] + fields = ['type','extension','need_infra','domaine_ip','domaine_range', 'vlan'] def __init__(self, *args, **kwargs): super(IpTypeForm, self).__init__(*args, **kwargs) @@ -151,7 +151,7 @@ class IpTypeForm(ModelForm): class EditIpTypeForm(IpTypeForm): class Meta(IpTypeForm.Meta): - fields = ['extension','type','need_infra'] + fields = ['extension','type','need_infra', 'vlan'] class DelIpTypeForm(Form): iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple) @@ -208,3 +208,13 @@ class ServiceForm(ModelForm): class DelServiceForm(Form): service = forms.ModelMultipleChoiceField(queryset=Service.objects.all(), label="Services actuels", widget=forms.CheckboxSelectMultiple) +class VlanForm(ModelForm): + class Meta: + model = Vlan + fields = '__all__' + +class DelVlanForm(Form): + vlan = forms.ModelMultipleChoiceField(queryset=Vlan.objects.all(), label="Vlan actuels", widget=forms.CheckboxSelectMultiple) + + + diff --git a/machines/migrations/0049_vlan.py b/machines/migrations/0049_vlan.py new file mode 100644 index 00000000..20a6905b --- /dev/null +++ b/machines/migrations/0049_vlan.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-08-25 21:07 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0048_auto_20170823_2315'), + ] + + operations = [ + migrations.CreateModel( + name='Vlan', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('vlan_id', models.IntegerField()), + ('name', models.CharField(max_length=256)), + ('comment', models.CharField(max_length=256)), + ], + ), + ] diff --git a/machines/migrations/0050_auto_20170826_0022.py b/machines/migrations/0050_auto_20170826_0022.py new file mode 100644 index 00000000..0f49a08b --- /dev/null +++ b/machines/migrations/0050_auto_20170826_0022.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-08-25 22:22 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0049_vlan'), + ] + + operations = [ + migrations.AlterField( + model_name='vlan', + name='comment', + field=models.CharField(blank=True, max_length=256), + ), + ] diff --git a/machines/migrations/0051_iptype_vlan.py b/machines/migrations/0051_iptype_vlan.py new file mode 100644 index 00000000..27b641b2 --- /dev/null +++ b/machines/migrations/0051_iptype_vlan.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-08-25 23:04 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0050_auto_20170826_0022'), + ] + + operations = [ + migrations.AddField( + model_name='iptype', + name='vlan', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='machines.Vlan'), + ), + ] diff --git a/machines/models.py b/machines/models.py index 9da62f5e..0866d4dc 100644 --- a/machines/models.py +++ b/machines/models.py @@ -69,6 +69,7 @@ class IpType(models.Model): need_infra = models.BooleanField(default=False) domaine_ip = models.GenericIPAddressField(protocol='IPv4') domaine_range = models.IntegerField(validators=[MinValueValidator(16), MaxValueValidator(32)]) + vlan = models.ForeignKey('Vlan', on_delete=models.PROTECT, blank=True, null=True) @cached_property def network(self): @@ -107,7 +108,7 @@ class IpType(models.Model): def clean(self): # On check que les / ne se recoupent pas - for element in IpType.objects.all(): + 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") return @@ -119,6 +120,16 @@ class IpType(models.Model): def __str__(self): return self.type +class Vlan(models.Model): + PRETTY_NAME = "Vlans" + + vlan_id = models.IntegerField() + name = models.CharField(max_length=256) + comment = models.CharField(max_length=256, blank=True) + + def __str__(self): + return self.name + class Extension(models.Model): PRETTY_NAME = "Extensions dns" @@ -360,7 +371,8 @@ def interface_post_delete(sender, **kwargs): @receiver(post_save, sender=IpType) def iptype_post_save(sender, **kwargs): iptype = kwargs['instance'] - iptype.gen_ip_range() + if not iptype.ip_objects(): + iptype.gen_ip_range() @receiver(post_save, sender=MachineType) def machine_post_save(sender, **kwargs): diff --git a/machines/templates/machines/aff_iptype.html b/machines/templates/machines/aff_iptype.html index 0bcb11b5..c0f6b880 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 Domaine d'ip Range + Sur vlan @@ -41,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ type.need_infra }} {{ type.domaine_ip }} {{ type.domaine_range }} + {{ type.vlan }} {% if is_infra %} {% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %} diff --git a/machines/templates/machines/aff_vlan.html b/machines/templates/machines/aff_vlan.html new file mode 100644 index 00000000..eaa1c82c --- /dev/null +++ b/machines/templates/machines/aff_vlan.html @@ -0,0 +1,50 @@ +{% 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 %} + + + + + + + + + + + + {% for vlan in vlan_list %} + + + + + + + + {% endfor %} +
IdNomCommentaireRanges ip
{{ vlan.vlan_id }}{{ vlan.name }}{{ vlan.comment }}{% for range in vlan.iptype_set.all %}{{ range }}, {% endfor%} + {% if is_infra %} + {% include 'buttons/edit.html' with href='machines:edit-vlan' id=vlan.id %} + {% endif %} + {% include 'buttons/history.html' with href='machines:history' name='vlan' id=vlan.id %} +
+ diff --git a/machines/templates/machines/index_vlan.html b/machines/templates/machines/index_vlan.html new file mode 100644 index 00000000..ccbfa753 --- /dev/null +++ b/machines/templates/machines/index_vlan.html @@ -0,0 +1,39 @@ +{% 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 %}Machines{% endblock %} + +{% block content %} +

Liste des vlans

+ Ajouter un vlan + Supprimer un ou plusieurs vlan + {% include "machines/aff_vlan.html" with vlan_list=vlan_list %} +
+
+
+{% endblock %} + diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index c4d98448..25c108cb 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -42,6 +42,10 @@ with this program; if not, write to the Free Software Foundation, Inc., Plages d'IP + + + Vlans + Services (dhcp, dns...) diff --git a/machines/urls.py b/machines/urls.py index b35e9d6f..07ad6129 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -56,6 +56,10 @@ urlpatterns = [ url(r'^edit_service/(?P[0-9]+)$', views.edit_service, name='edit-service'), url(r'^del_service/$', views.del_service, name='del-service'), url(r'^index_service/$', views.index_service, name='index-service'), + url(r'^add_vlan/$', views.add_vlan, name='add-vlan'), + url(r'^edit_vlan/(?P[0-9]+)$', views.edit_vlan, name='edit-vlan'), + url(r'^del_vlan/$', views.del_vlan, name='del-vlan'), + url(r'^index_vlan/$', views.index_vlan, name='index-vlan'), url(r'^history/(?Pmachine)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Pinterface)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Pmachinetype)/(?P[0-9]+)$', views.history, name='history'), @@ -64,6 +68,7 @@ urlpatterns = [ url(r'^history/(?Pns)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Piptype)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Palias)/(?P[0-9]+)$', views.history, name='history'), + url(r'^history/(?Pvlan)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Pservice)/(?P[0-9]+)$', views.history, name='history'), url(r'^$', views.index, name='index'), url(r'^rest/mac-ip/$', views.mac_ip, name='mac-ip'), diff --git a/machines/views.py b/machines/views.py index a3b20312..fb4b7a46 100644 --- a/machines/views.py +++ b/machines/views.py @@ -44,8 +44,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, MxForm, DelMxForm, ServiceForm, DelServiceForm -from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link +from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm +from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan from users.models import User from users.models import all_has_access from preferences.models import GeneralOption, OptionalMachine @@ -592,6 +592,54 @@ def del_service(request): return redirect("/machines/index_service") return form({'machineform': service}, 'machines/machine.html', request) +@login_required +@permission_required('infra') +def add_vlan(request): + vlan = VlanForm(request.POST or None) + if vlan.is_valid(): + with transaction.atomic(), reversion.create_revision(): + vlan.save() + reversion.set_user(request.user) + reversion.set_comment("Création") + messages.success(request, "Cet enregistrement vlan a été ajouté") + return redirect("/machines/index_vlan") + return form({'machineform': vlan, 'interfaceform': None}, 'machines/machine.html', request) + +@login_required +@permission_required('infra') +def edit_vlan(request, vlanid): + try: + vlan_instance = Vlan.objects.get(pk=vlanid) + except Vlan.DoesNotExist: + messages.error(request, u"Entrée inexistante" ) + return redirect("/machines/index_vlan/") + vlan = VlanForm(request.POST or None, instance=vlan_instance) + if vlan.is_valid(): + with transaction.atomic(), reversion.create_revision(): + vlan.save() + reversion.set_user(request.user) + reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in vlan.changed_data)) + messages.success(request, "Vlan modifié") + return redirect("/machines/index_vlan/") + return form({'machineform': vlan}, 'machines/machine.html', request) + +@login_required +@permission_required('infra') +def del_vlan(request): + vlan = DelVlanForm(request.POST or None) + if vlan.is_valid(): + vlan_dels = vlan.cleaned_data['vlan'] + for vlan_del in ns_dels: + try: + with transaction.atomic(), reversion.create_revision(): + vlan_del.delete() + reversion.set_user(request.user) + messages.success(request, "Le vlan a été supprimée") + except ProtectedError: + messages.error(request, "Erreur le Vlan suivant %s ne peut être supprimé" % vlan_del) + return redirect("/machines/index_vlan") + return form({'machineform': vlan, 'interfaceform': None}, 'machines/machine.html', request) + @login_required @permission_required('cableur') def index(request): @@ -616,6 +664,12 @@ def index_iptype(request): iptype_list = IpType.objects.select_related('extension').order_by('type') return render(request, 'machines/index_iptype.html', {'iptype_list':iptype_list}) +@login_required +@permission_required('cableur') +def index_vlan(request): + vlan_list = Vlan.objects.order_by('vlan_id') + return render(request, 'machines/index_vlan.html', {'vlan_list':vlan_list}) + @login_required @permission_required('cableur') def index_machinetype(request): @@ -715,6 +769,12 @@ def history(request, object, id): except Service.DoesNotExist: messages.error(request, "Service inexistant") return redirect("/machines/") + elif object == 'vlan' and request.user.has_perms(('cableur',)): + try: + object_instance = Vlan.objects.get(pk=id) + except Vlan.DoesNotExist: + messages.error(request, "Vlan inexistant") + return redirect("/machines/") else: messages.error(request, "Objet inconnu") return redirect("/machines/") diff --git a/preferences/admin.py b/preferences/admin.py index e1806c5a..d4c41e62 100644 --- a/preferences/admin.py +++ b/preferences/admin.py @@ -23,11 +23,15 @@ from django.contrib import admin from reversion.admin import VersionAdmin -from .models import OptionalUser, OptionalMachine, GeneralOption, Service, AssoOption +from .models import OptionalUser, OptionalMachine, OptionalTopologie, GeneralOption, Service, AssoOption class OptionalUserAdmin(VersionAdmin): pass +class OptionalTopologieAdmin(VersionAdmin): + pass + + class OptionalMachineAdmin(VersionAdmin): pass @@ -42,6 +46,7 @@ class AssoOptionAdmin(VersionAdmin): admin.site.register(OptionalUser, OptionalUserAdmin) admin.site.register(OptionalMachine, OptionalMachineAdmin) +admin.site.register(OptionalTopologie, OptionalTopologieAdmin) admin.site.register(GeneralOption, GeneralOptionAdmin) admin.site.register(Service, ServiceAdmin) admin.site.register(AssoOption, AssoOptionAdmin) diff --git a/preferences/forms.py b/preferences/forms.py index 4c9024d6..37e9c7ea 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -22,7 +22,7 @@ from django.forms import ModelForm, Form, ValidationError from django import forms -from .models import OptionalUser, OptionalMachine, GeneralOption, AssoOption, Service +from .models import OptionalUser, OptionalMachine, OptionalTopologie, GeneralOption, AssoOption, Service from django.db.models import Q class EditOptionalUserForm(ModelForm): @@ -46,6 +46,15 @@ class EditOptionalMachineForm(ModelForm): self.fields['max_lambdauser_interfaces'].label = "Maximum d'interfaces autorisées pour un user normal" self.fields['max_lambdauser_aliases'].label = "Maximum d'alias dns autorisés pour un user normal" +class EditOptionalTopologieForm(ModelForm): + class Meta: + model = OptionalTopologie + fields = '__all__' + + def __init__(self, *args, **kwargs): + super(EditOptionalTopologieForm, self).__init__(*args, **kwargs) + self.fields['vlan_decision_ok'].label = "Vlan où placer les machines après acceptation RADIUS" + self.fields['vlan_decision_nok'].label = "Vlan où placer les machines après rejet RADIUS" class EditGeneralOptionForm(ModelForm): class Meta: diff --git a/preferences/migrations/0010_auto_20170825_0459.py b/preferences/migrations/0010_auto_20170825_0459.py new file mode 100644 index 00000000..9d8a2cb5 --- /dev/null +++ b/preferences/migrations/0010_auto_20170825_0459.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-08-25 02:59 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('preferences', '0009_assooption_utilisateur_asso'), + ] + + operations = [ + migrations.CreateModel( + name='OptionalTopologie', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.CreateModel( + name='Vlan', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('vlan_id', models.IntegerField()), + ('comment', models.CharField(max_length=256)), + ], + ), + migrations.AddField( + model_name='optionaltopologie', + name='vlan_decision_nok', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='decision_nok', to='preferences.Vlan'), + ), + migrations.AddField( + model_name='optionaltopologie', + name='vlan_decision_ok', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='decision_ok', to='preferences.Vlan'), + ), + ] diff --git a/preferences/migrations/0011_auto_20170825_2307.py b/preferences/migrations/0011_auto_20170825_2307.py new file mode 100644 index 00000000..58ad054f --- /dev/null +++ b/preferences/migrations/0011_auto_20170825_2307.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-08-25 21:07 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('preferences', '0010_auto_20170825_0459'), + ] + + operations = [ + migrations.AlterField( + model_name='optionaltopologie', + name='vlan_decision_nok', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='decision_nok', to='machines.Vlan'), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='vlan_decision_ok', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='decision_ok', to='machines.Vlan'), + ), + migrations.DeleteModel( + name='Vlan', + ), + ] diff --git a/preferences/models.py b/preferences/models.py index d87c1eb4..8c806d93 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -23,6 +23,7 @@ from django.db import models from cotisations.models import Paiement +from machines.models import Vlan class OptionalUser(models.Model): PRETTY_NAME = "Options utilisateur" @@ -43,8 +44,11 @@ class OptionalMachine(models.Model): max_lambdauser_interfaces = models.IntegerField(default=10) max_lambdauser_aliases = models.IntegerField(default=10) -#class OptionalTopologie(models.Model): +class OptionalTopologie(models.Model): + PRETTY_NAME = "Options topologie" + vlan_decision_ok = models.OneToOneField('machines.Vlan', on_delete=models.PROTECT, related_name='decision_ok', blank=True, null=True) + vlan_decision_nok = models.OneToOneField('machines.Vlan', on_delete=models.PROTECT, related_name='decision_nok', blank=True, null=True) class GeneralOption(models.Model): PRETTY_NAME = "Options générales" diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index dd6f6996..60b11543 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -70,6 +70,23 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ machineoptions.max_lambdauser_aliases }} +

Préférences topologie

+ {% if is_bureau %} + + + Editer + + {% endif %} +

+

+ + + + + + + +
Vlan où placer les machines après acceptation RADIUS{{ topologieoptions.vlan_decision_ok }}Vlan où placer les machines après rejet RADIUS{{ topologieoptions.vlan_decision_nok }}

Préférences generales

{% if is_bureau %} diff --git a/preferences/urls.py b/preferences/urls.py index 17119d4e..dd9ccd8b 100644 --- a/preferences/urls.py +++ b/preferences/urls.py @@ -28,6 +28,7 @@ from . import views urlpatterns = [ url(r'^edit_options/(?P
OptionalUser)$', views.edit_options, name='edit-options'), url(r'^edit_options/(?P
OptionalMachine)$', views.edit_options, name='edit-options'), + url(r'^edit_options/(?P
OptionalTopologie)$', views.edit_options, name='edit-options'), url(r'^edit_options/(?P
GeneralOption)$', views.edit_options, name='edit-options'), url(r'^edit_options/(?P
AssoOption)$', views.edit_options, name='edit-options'), url(r'^add_services/$', views.add_services, name='add-services'), diff --git a/preferences/views.py b/preferences/views.py index 8176ba9b..dc29aee2 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -43,7 +43,7 @@ from reversion.models import Version from reversion import revisions as reversion from .forms import ServiceForm, DelServiceForm -from .models import Service, OptionalUser, OptionalMachine, AssoOption, GeneralOption +from .models import Service, OptionalUser, OptionalMachine, AssoOption, GeneralOption, OptionalTopologie from . import models from . import forms @@ -58,10 +58,11 @@ def form(ctx, template, request): def display_options(request): useroptions, created = OptionalUser.objects.get_or_create() machineoptions, created = OptionalMachine.objects.get_or_create() + topologieoptions, created = OptionalTopologie.objects.get_or_create() generaloptions, created = GeneralOption.objects.get_or_create() assooptions, crated = AssoOption.objects.get_or_create() service_list = Service.objects.all() - return form({'useroptions': useroptions, 'machineoptions': machineoptions, 'generaloptions': generaloptions, 'assooptions' : assooptions, 'service_list':service_list}, 'preferences/display_preferences.html', request) + return form({'useroptions': useroptions, 'machineoptions': machineoptions, 'topologieoptions': topologieoptions, 'generaloptions': generaloptions, 'assooptions' : assooptions, 'service_list':service_list}, 'preferences/display_preferences.html', request) @login_required @permission_required('admin') diff --git a/re2o/settings_local.example.py b/re2o/settings_local.example.py index 0d684310..b5fe323c 100644 --- a/re2o/settings_local.example.py +++ b/re2o/settings_local.example.py @@ -98,14 +98,5 @@ GID_RANGES = { 'posix' : [501, 600], } -# Liste des vlans id disponible sur un switch -VLAN_ID_LIST = [7,8,42,69] - -# Décision radius à prendre -RADIUS_VLAN_DECISION = { - 'VLAN_NOK' : 42, - 'VLAN_OK' : 69, -} - OPTIONNAL_APPS = () diff --git a/topologie/models.py b/topologie/models.py index 39123086..e64a9e51 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -27,7 +27,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.core.exceptions import ValidationError import reversion -from re2o.settings import VLAN_ID_LIST +from machines.models import Vlan def make_port_related(port): related_port = port.related @@ -58,7 +58,7 @@ class Port(models.Model): ('BLOQ', 'BLOQ'), ('COMMON', 'COMMON'), ) - STATES = STATES_BASE + tuple([(str(id), str(id)) for id in VLAN_ID_LIST]) + STATES = STATES_BASE + tuple([(str(id), str(id)) for id in list(Vlan.objects.values_list('vlan_id', flat=True).order_by('vlan_id'))]) switch = models.ForeignKey('Switch', related_name="ports") port = models.IntegerField() diff --git a/users/models.py b/users/models.py index e2f2c818..26619014 100644 --- a/users/models.py +++ b/users/models.py @@ -74,7 +74,7 @@ def linux_user_validator(login): def get_fresh_user_uid(): uids = list(range(int(min(UID_RANGES['users'])),int(max(UID_RANGES['users'])))) try: - used_uids = [ user.uid_number for user in User.objects.all()] + used_uids = list(User.objects.values_list('uid_number', flat=True)) except: used_uids = [] free_uids = [ id for id in uids if id not in used_uids] @@ -82,7 +82,7 @@ def get_fresh_user_uid(): def get_fresh_gid(): gids = list(range(int(min(GID_RANGES['posix'])),int(max(GID_RANGES['posix'])))) - used_gids = [ right.gid for right in ListRight.objects.all()] + used_gids = list(ListRight.objects.values_list('gid', flat=True)) free_gids = [ id for id in gids if id not in used_gids] return min(free_gids) @@ -462,7 +462,7 @@ class ServiceUser(AbstractBaseUser): group = LdapServiceUserGroup.objects.get(name=self.access_group) except: group = LdapServiceUserGroup(name=self.access_group) - group.members = [serviceuser.dn for serviceuser in LdapServiceUser.objects.filter(name__in=[user.pseudo for user in ServiceUser.objects.filter(access_group=self.access_group)])] + group.members = list(LdapServiceUser.objects.filter(name__in=[user.pseudo for user in ServiceUser.objects.filter(access_group=self.access_group)]).values_list('dn', flat=True)) group.save() def __str__(self):