mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-08-19 13:43:40 +00:00
Omnibus : ajout du suport de la liste vlan + corrections mineures
This commit is contained in:
parent
f6d7e02b0c
commit
0719e89a8b
25 changed files with 386 additions and 38 deletions
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
24
machines/migrations/0049_vlan.py
Normal file
24
machines/migrations/0049_vlan.py
Normal file
|
@ -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)),
|
||||
],
|
||||
),
|
||||
]
|
20
machines/migrations/0050_auto_20170826_0022.py
Normal file
20
machines/migrations/0050_auto_20170826_0022.py
Normal file
|
@ -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),
|
||||
),
|
||||
]
|
21
machines/migrations/0051_iptype_vlan.py
Normal file
21
machines/migrations/0051_iptype_vlan.py
Normal file
|
@ -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'),
|
||||
),
|
||||
]
|
|
@ -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):
|
||||
|
|
|
@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
<th>Nécessite l'autorisation infra</th>
|
||||
<th>Domaine d'ip</th>
|
||||
<th>Range</th>
|
||||
<th>Sur vlan</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -41,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
<td>{{ type.need_infra }}</td>
|
||||
<td>{{ type.domaine_ip }}</td>
|
||||
<td>{{ type.domaine_range }}</td>
|
||||
<td>{{ type.vlan }}</td>
|
||||
<td class="text-right">
|
||||
{% if is_infra %}
|
||||
{% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %}
|
||||
|
|
50
machines/templates/machines/aff_vlan.html
Normal file
50
machines/templates/machines/aff_vlan.html
Normal file
|
@ -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 %}
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Nom</th>
|
||||
<th>Commentaire</th>
|
||||
<th>Ranges ip</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for vlan in vlan_list %}
|
||||
<tr>
|
||||
<td>{{ vlan.vlan_id }}</td>
|
||||
<td>{{ vlan.name }}</td>
|
||||
<td>{{ vlan.comment }}</td>
|
||||
<td>{% for range in vlan.iptype_set.all %}{{ range }}, {% endfor%}</td>
|
||||
<td class="text-right">
|
||||
{% 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 %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
39
machines/templates/machines/index_vlan.html
Normal file
39
machines/templates/machines/index_vlan.html
Normal file
|
@ -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 %}
|
||||
<h2>Liste des vlans</h2>
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:add-vlan' %}"><i class="glyphicon glyphicon-plus"></i> Ajouter un vlan</a>
|
||||
<a class="btn btn-danger btn-sm" role="button" href="{% url 'machines:del-vlan' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un ou plusieurs vlan</a>
|
||||
{% include "machines/aff_vlan.html" with vlan_list=vlan_list %}
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% endblock %}
|
||||
|
|
@ -42,6 +42,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
<i class="glyphicon glyphicon-list"></i>
|
||||
Plages d'IP
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-info" href="{% url "machines:index-vlan" %}">
|
||||
<i class="glyphicon glyphicon-list"></i>
|
||||
Vlans
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-info" href="{% url "machines:index-service" %}">
|
||||
<i class="glyphicon glyphicon-list"></i>
|
||||
Services (dhcp, dns...)
|
||||
|
|
|
@ -56,6 +56,10 @@ urlpatterns = [
|
|||
url(r'^edit_service/(?P<serviceid>[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<vlanid>[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/(?P<object>machine)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^history/(?P<object>interface)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^history/(?P<object>machinetype)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
|
@ -64,6 +68,7 @@ urlpatterns = [
|
|||
url(r'^history/(?P<object>ns)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^history/(?P<object>iptype)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^history/(?P<object>alias)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^history/(?P<object>vlan)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^history/(?P<object>service)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^rest/mac-ip/$', views.mac_ip, name='mac-ip'),
|
||||
|
|
|
@ -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/")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
40
preferences/migrations/0010_auto_20170825_0459.py
Normal file
40
preferences/migrations/0010_auto_20170825_0459.py
Normal file
|
@ -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'),
|
||||
),
|
||||
]
|
29
preferences/migrations/0011_auto_20170825_2307.py
Normal file
29
preferences/migrations/0011_auto_20170825_2307.py
Normal file
|
@ -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',
|
||||
),
|
||||
]
|
|
@ -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"
|
||||
|
|
|
@ -70,6 +70,23 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
<td>{{ machineoptions.max_lambdauser_aliases }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>Préférences topologie</h4>
|
||||
{% if is_bureau %}
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalTopologie' %}">
|
||||
<i class="glyphicon glyphicon-edit"></i>
|
||||
Editer
|
||||
</a>
|
||||
{% endif %}
|
||||
<p>
|
||||
</p>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Vlan où placer les machines après acceptation RADIUS</th>
|
||||
<td>{{ topologieoptions.vlan_decision_ok }}</td>
|
||||
<th>Vlan où placer les machines après rejet RADIUS</th>
|
||||
<td>{{ topologieoptions.vlan_decision_nok }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>Préférences generales</h4>
|
||||
{% if is_bureau %}
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'GeneralOption' %}">
|
||||
|
|
|
@ -28,6 +28,7 @@ from . import views
|
|||
urlpatterns = [
|
||||
url(r'^edit_options/(?P<section>OptionalUser)$', views.edit_options, name='edit-options'),
|
||||
url(r'^edit_options/(?P<section>OptionalMachine)$', views.edit_options, name='edit-options'),
|
||||
url(r'^edit_options/(?P<section>OptionalTopologie)$', views.edit_options, name='edit-options'),
|
||||
url(r'^edit_options/(?P<section>GeneralOption)$', views.edit_options, name='edit-options'),
|
||||
url(r'^edit_options/(?P<section>AssoOption)$', views.edit_options, name='edit-options'),
|
||||
url(r'^add_services/$', views.add_services, name='add-services'),
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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 = ()
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue