8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-23 20:03:11 +00:00

Merge branch 'new_upstream' into 'master'

New upstream

See merge request nounous/re2o!13
This commit is contained in:
Gabriel Detraz 2018-03-27 01:30:18 +02:00
commit 835525a877
29 changed files with 578 additions and 231 deletions

View file

@ -192,19 +192,21 @@ def post_auth(data):
mac = data.get('Calling-Station-Id', None) mac = data.get('Calling-Station-Id', None)
# Switch et bornes héritent de machine et peuvent avoir plusieurs interfaces filles
nas_machine = nas_instance.machine
# Si il s'agit d'un switch # Si il s'agit d'un switch
if hasattr(nas_instance, 'switch'): if hasattr(nas_machine, 'switch'):
port = data.get('NAS-Port-Id', data.get('NAS-Port', None)) port = data.get('NAS-Port-Id', data.get('NAS-Port', None))
#Pour les infrastructures possédant des switchs Juniper : #Pour les infrastructures possédant des switchs Juniper :
#On vérifie si le switch fait partie d'un stack Juniper #On vérifie si le switch fait partie d'un stack Juniper
instance_stack = nas_instance.switch.stack instance_stack = nas_machine.switch.stack
if instance_stack: if instance_stack:
# Si c'est le cas, on resélectionne le bon switch dans la stack # Si c'est le cas, on resélectionne le bon switch dans la stack
id_stack_member = port.split("-")[1].split('/')[0] id_stack_member = port.split("-")[1].split('/')[0]
nas_instance = Interface.objects.filter(switch__in=Switch.objects.filter(stack=instance_stack).filter(stack_member_id=id_stack_member)).select_related('domain__extension').first() nas_machine = Switch.objects.filter(stack=instance_stack).filter(stack_member_id=id_stack_member).prefetch_related('interface_set__domain__extension').first()
# On récupère le numéro du port sur l'output de freeradius. La ligne suivante fonctionne pour cisco, HP et Juniper # On récupère le numéro du port sur l'output de freeradius. La ligne suivante fonctionne pour cisco, HP et Juniper
port = port.split(".")[0].split('/')[-1][-2:] port = port.split(".")[0].split('/')[-1][-2:]
out = decide_vlan_and_register_switch(nas_instance, nas_type, port, mac) out = decide_vlan_and_register_switch(nas_machine, nas_type, port, mac)
sw_name, room, reason, vlan_id = out sw_name, room, reason, vlan_id = out
log_message = '(fil) %s -> %s [%s%s]' % \ log_message = '(fil) %s -> %s [%s%s]' % \
@ -271,7 +273,7 @@ def check_user_machine_and_register(nas_type, username, mac_address):
return (False, u"Machine inconnue", '') return (False, u"Machine inconnue", '')
def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address): def decide_vlan_and_register_switch(nas_machine, nas_type, port_number, mac_address):
"""Fonction de placement vlan pour un switch en radius filaire auth par mac. """Fonction de placement vlan pour un switch en radius filaire auth par mac.
Plusieurs modes : Plusieurs modes :
- nas inconnu, port inconnu : on place sur le vlan par defaut VLAN_OK - nas inconnu, port inconnu : on place sur le vlan par defaut VLAN_OK
@ -296,12 +298,12 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
# Get port from switch and port number # Get port from switch and port number
extra_log = "" extra_log = ""
# Si le NAS est inconnu, on place sur le vlan defaut # Si le NAS est inconnu, on place sur le vlan defaut
if not nas: if not nas_machine:
return ('?', u'Chambre inconnue', u'Nas inconnu', VLAN_OK) return ('?', u'Chambre inconnue', u'Nas inconnu', VLAN_OK)
sw_name = str(nas) sw_name = str(nas_machine)
port = Port.objects.filter(switch=Switch.objects.filter(interface_ptr=nas), port=port_number).first() port = Port.objects.filter(switch=Switch.objects.filter(machine_ptr=nas_machine), port=port_number).first()
#Si le port est inconnu, on place sur le vlan defaut #Si le port est inconnu, on place sur le vlan defaut
if not port: if not port:
return (sw_name, "Chambre inconnue", u'Port inconnu', VLAN_OK) return (sw_name, "Chambre inconnue", u'Port inconnu', VLAN_OK)

View file

@ -42,8 +42,7 @@ from django.shortcuts import render, redirect
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Count from django.db.models import Count, Max
from django.db.models import Max
from reversion.models import Revision from reversion.models import Revision
from reversion.models import Version, ContentType from reversion.models import Version, ContentType
@ -457,7 +456,7 @@ def stats_droits(request):
depart=time() depart=time()
stats_list={} stats_list={}
for droit in ListRight.objects.all().select_related('group_ptr'):#.prefetch_related('group_ptr__user_set__revision_set'): for droit in ListRight.objects.all().select_related('group_ptr'):
stats_list[droit]=droit.user_set.all().annotate(num=Count('revision'),last=Max('revision__date_created')) stats_list[droit]=droit.user_set.all().annotate(num=Count('revision'),last=Max('revision__date_created'))
return render(request, 'logs/stats_droits.html', {'stats_list': stats_list}) return render(request, 'logs/stats_droits.html', {'stats_list': stats_list})

View file

@ -122,6 +122,7 @@ MODEL_NAME = {
# topologie # topologie
'Stack' : topologie.models.Stack, 'Stack' : topologie.models.Stack,
'Switch' : topologie.models.Switch, 'Switch' : topologie.models.Switch,
'AccessPoint' : topologie.models.AccessPoint,
'ModelSwitch' : topologie.models.ModelSwitch, 'ModelSwitch' : topologie.models.ModelSwitch,
'ConstructorSwitch' : topologie.models.ConstructorSwitch, 'ConstructorSwitch' : topologie.models.ConstructorSwitch,
'Port' : topologie.models.Port, 'Port' : topologie.models.Port,

View file

@ -213,8 +213,8 @@ class SortTable:
'default': ['-date'] 'default': ['-date']
} }
TOPOLOGIE_INDEX = { TOPOLOGIE_INDEX = {
'switch_dns': ['switch_interface__domain__name'], 'switch_dns': ['interface__domain__name'],
'switch_ip': ['switch_interface__ipv4__ipv4'], 'switch_ip': ['interface__ipv4__ipv4'],
'switch_loc': ['location'], 'switch_loc': ['location'],
'switch_ports': ['number'], 'switch_ports': ['number'],
'switch_stack': ['stack__name'], 'switch_stack': ['stack__name'],
@ -234,10 +234,10 @@ class SortTable:
'default': ['name'] 'default': ['name']
} }
TOPOLOGIE_INDEX_BORNE = { TOPOLOGIE_INDEX_BORNE = {
'borne_name': ['domain__name'], 'ap_name': ['interface__domain__name'],
'borne_ip': ['ipv4__ipv4'], 'ap_ip': ['interface__ipv4__ipv4'],
'borne_mac': ['mac_address'], 'ap_mac': ['interface__mac_address'],
'default': ['domain__name'] 'default': ['interface__domain__name']
} }
TOPOLOGIE_INDEX_STACK = { TOPOLOGIE_INDEX_STACK = {
'stack_name': ['name'], 'stack_name': ['name'],

View file

@ -83,7 +83,7 @@ HISTORY_BIND = {
'stack' : topologie.models.Stack, 'stack' : topologie.models.Stack,
'model_switch' : topologie.models.ModelSwitch, 'model_switch' : topologie.models.ModelSwitch,
'constructor_switch' : topologie.models.ConstructorSwitch, 'constructor_switch' : topologie.models.ConstructorSwitch,
'borne' : topologie.models.Borne, 'ap' : topologie.models.AccessPoint,
}, },
'machines' : { 'machines' : {
'machine' : machines.models.Machine, 'machine' : machines.models.Machine,

View file

@ -260,7 +260,7 @@ def search_single_word(word, filters, user,
) | Q( ) | Q(
machine_interface__domain__name__icontains=word machine_interface__domain__name__icontains=word
) | Q( ) | Q(
related__switch__switch_interface__domain__name__icontains=word related__switch__domain__name__icontains=word
) | Q( ) | Q(
radius__icontains=word radius__icontains=word
) | Q( ) | Q(
@ -277,9 +277,9 @@ def search_single_word(word, filters, user,
# Switches # Switches
if '7' in aff and Switch.can_view_all(user): if '7' in aff and Switch.can_view_all(user):
filter_switches = Q( filter_switches = Q(
switch_interface__domain__name__icontains=word domain__name__icontains=word
) | Q( ) | Q(
switch_interface__ipv4__ipv4__icontains=word ipv4__ipv4__icontains=word
) | Q( ) | Q(
location__icontains=word location__icontains=word
) | Q( ) | Q(

View file

@ -36,7 +36,7 @@ from .models import (
Stack, Stack,
ModelSwitch, ModelSwitch,
ConstructorSwitch, ConstructorSwitch,
Borne AccessPoint
) )
@ -55,7 +55,7 @@ class PortAdmin(VersionAdmin):
pass pass
class BorneAdmin(VersionAdmin): class AccessPointAdmin(VersionAdmin):
"""Administration d'une borne""" """Administration d'une borne"""
pass pass
@ -76,7 +76,7 @@ class ConstructorSwitchAdmin(VersionAdmin):
admin.site.register(Port, PortAdmin) admin.site.register(Port, PortAdmin)
admin.site.register(Borne, BorneAdmin) admin.site.register(AccessPoint, AccessPointAdmin)
admin.site.register(Room, RoomAdmin) admin.site.register(Room, RoomAdmin)
admin.site.register(Switch, SwitchAdmin) admin.site.register(Switch, SwitchAdmin)
admin.site.register(Stack, StackAdmin) admin.site.register(Stack, StackAdmin)

View file

@ -33,9 +33,14 @@ NewSwitchForm)
from __future__ import unicode_literals from __future__ import unicode_literals
from machines.models import Interface from machines.models import Interface
from machines.forms import EditInterfaceForm from machines.forms import (
EditInterfaceForm,
EditMachineForm,
NewMachineForm
)
from django import forms from django import forms
from django.forms import ModelForm, Form from django.forms import ModelForm, Form
from django.db.models import Prefetch
from .models import ( from .models import (
Port, Port,
Switch, Switch,
@ -43,7 +48,7 @@ from .models import (
Stack, Stack,
ModelSwitch, ModelSwitch,
ConstructorSwitch, ConstructorSwitch,
Borne AccessPoint
) )
@ -78,8 +83,10 @@ class EditPortForm(ModelForm):
self.fields['machine_interface'].queryset = Interface.objects.all()\ self.fields['machine_interface'].queryset = Interface.objects.all()\
.select_related('domain__extension') .select_related('domain__extension')
self.fields['related'].queryset = Port.objects.all()\ self.fields['related'].queryset = Port.objects.all()\
.select_related('switch__domain__extension')\ .prefetch_related(Prefetch(
.order_by('switch', 'port') 'switch__interface_set',
queryset=Interface.objects.select_related('ipv4__ip_type__extension').select_related('domain__extension')
))
class AddPortForm(ModelForm): class AddPortForm(ModelForm):
@ -95,8 +102,10 @@ class AddPortForm(ModelForm):
self.fields['machine_interface'].queryset = Interface.objects.all()\ self.fields['machine_interface'].queryset = Interface.objects.all()\
.select_related('domain__extension') .select_related('domain__extension')
self.fields['related'].queryset = Port.objects.all()\ self.fields['related'].queryset = Port.objects.all()\
.select_related('switch__domain__extension')\ .prefetch_related(Prefetch(
.order_by('switch', 'port') 'switch__interface_set',
queryset=Interface.objects.select_related('ipv4__ip_type__extension').select_related('domain__extension')
))
class StackForm(ModelForm): class StackForm(ModelForm):
@ -111,33 +120,33 @@ class StackForm(ModelForm):
super(StackForm, self).__init__(*args, prefix=prefix, **kwargs) super(StackForm, self).__init__(*args, prefix=prefix, **kwargs)
class AddBorneForm(EditInterfaceForm): class AddAccessPointForm(NewMachineForm):
"""Formulaire pour la création d'une borne """Formulaire pour la création d'une borne
Relié directement au modèle borne""" Relié directement au modèle borne"""
class Meta: class Meta:
model = Borne model = AccessPoint
fields = ['mac_address', 'type', 'ipv4', 'details', 'location'] fields = ['location', 'name']
class EditBorneForm(EditInterfaceForm): class EditAccessPointForm(EditMachineForm):
"""Edition d'une interface. Edition complète""" """Edition d'une borne. Edition complète"""
class Meta: class Meta:
model = Borne model = AccessPoint
fields = ['machine', 'type', 'ipv4', 'mac_address', 'details', 'location'] fields = '__all__'
class EditSwitchForm(EditInterfaceForm): class EditSwitchForm(EditMachineForm):
"""Permet d'éditer un switch : nom et nombre de ports""" """Permet d'éditer un switch : nom et nombre de ports"""
class Meta: class Meta:
model = Switch model = Switch
fields = ['machine', 'type', 'ipv4', 'mac_address', 'details', 'location', 'number', 'stack', 'stack_member_id'] fields = '__all__'
class NewSwitchForm(EditInterfaceForm): class NewSwitchForm(NewMachineForm):
"""Permet de créer un switch : emplacement, paramètres machine, """Permet de créer un switch : emplacement, paramètres machine,
membre d'un stack (option), nombre de ports (number)""" membre d'un stack (option), nombre de ports (number)"""
class Meta(EditSwitchForm.Meta): class Meta(EditSwitchForm.Meta):
fields = ['type', 'ipv4', 'mac_address', 'details', 'location', 'number', 'stack', 'stack_member_id'] fields = ['name', 'location', 'number', 'stack', 'stack_member_id']
class EditRoomForm(ModelForm): class EditRoomForm(ModelForm):

View file

@ -12,6 +12,10 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.AlterUniqueTogether(
name='port',
unique_together=set([]),
),
migrations.RemoveField( migrations.RemoveField(
model_name='port', model_name='port',
name='switch', name='switch',

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-25 22:02
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0043_renamenewswitch'),
]
operations = [
migrations.RenameModel(
old_name='Borne',
new_name='AccessPoint',
),
migrations.AlterModelOptions(
name='accesspoint',
options={'permissions': (('view_ap', 'Peut voir une borne'),)},
),
migrations.AlterModelOptions(
name='switch',
options={'permissions': (('view_switch', 'Peut voir un objet switch'),)},
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-25 23:23
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0044_auto_20180326_0002'),
]
operations = [
migrations.AlterField(
model_name='port',
name='switch',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ports', to='topologie.Switch'),
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-25 23:29
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('topologie', '0045_auto_20180326_0123'),
]
operations = [
migrations.AlterUniqueTogether(
name='port',
unique_together=set([('switch', 'port')]),
),
]

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-23 01:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0046_auto_20180326_0129'),
]
operations = [
migrations.CreateModel(
name='NewAccessPoint',
fields=[
('machine_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='machines.Machine')),
('location', models.CharField(help_text="Détails sur la localisation de l'AP", max_length=255, null=True, blank=True)),
],
bases=('machines.machine',),
),
]

View file

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-23 01:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0047_ap_machine'),
]
def transfer_ap(apps, schema_editor):
db_alias = schema_editor.connection.alias
ap = apps.get_model("topologie", "AccessPoint")
new_ap = apps.get_model("topologie", "NewAccessPoint")
ap_list = ap.objects.using(db_alias).all()
for borne in ap_list:
new_borne = new_ap()
new_borne.machine_ptr_id = borne.machine.pk
new_borne.__dict__.update(borne.machine.__dict__)
new_borne.location = borne.location
new_borne.save()
def untransfer_ap(apps, schema_editor):
return
operations = [
migrations.RunPython(transfer_ap, untransfer_ap),
migrations.DeleteModel(
name='AccessPoint',
),
migrations.RenameModel(
old_name='NewAccessPoint',
new_name='AccessPoint',
),
]

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-23 01:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0048_ap_machine'),
]
operations = [
migrations.CreateModel(
name='NewSw',
fields=[
('machine_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='machines.Machine')),
('location', models.CharField(max_length=255)),
('number', models.PositiveIntegerField()),
('stack_member_id', models.PositiveIntegerField(blank=True, null=True)),
('model', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='topologie.ModelSwitch')),
('stack', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='topologie.Stack')),
],
bases=('machines.machine',),
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-25 00:52
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0049_switchs_machine'),
]
operations = [
migrations.AddField(
model_name='port',
name='new_sw',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ports', to='topologie.NewSw'),
),
]

View file

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-23 01:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0050_port_new_switch'),
]
def transfer_sw(apps, schema_editor):
db_alias = schema_editor.connection.alias
newswitch = apps.get_model("topologie", "NewSw")
switch = apps.get_model("topologie", "Switch")
machine = apps.get_model("machines", "Machine")
sw_list = switch.objects.using(db_alias).all()
for sw in sw_list:
new_sw = newswitch()
new_sw.location = sw.location
new_sw.number = sw.number
new_sw.details = sw.details
new_sw.stack = sw.stack
new_sw.stack_member_id = sw.stack_member_id
new_sw.model = sw.model
new_sw.machine_ptr_id = sw.interface_ptr.machine.pk
new_sw.__dict__.update(sw.interface_ptr.machine.__dict__)
new_sw.save()
def untransfer_sw(apps, schema_editor):
return
operations = [
migrations.RunPython(transfer_sw, untransfer_sw),
]

View file

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-31 19:53
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('topologie', '0051_switchs_machine'),
]
def transfer_port(apps, schema_editor):
db_alias = schema_editor.connection.alias
port = apps.get_model("topologie", "Port")
switch = apps.get_model("topologie", "NewSw")
port_list = port.objects.using(db_alias).all()
for p in port_list:
p.new_sw = switch.objects.filter(machine_ptr=p.switch.machine).first()
p.save()
def untransfer_port(apps, schema_editor):
return
operations = [
migrations.AlterUniqueTogether(
name='port',
unique_together=set([]),
),
migrations.RunPython(transfer_port, untransfer_port),
migrations.RemoveField(
model_name='port',
name='switch',
),
migrations.RenameField('Port', 'new_sw', 'switch')
]

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-23 01:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0052_transferports'),
]
operations = [
migrations.DeleteModel(
name='Switch',
),
migrations.RenameModel(
old_name='NewSw',
new_name='Switch',
),
]

View file

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-03-26 15:42
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0053_finalsw'),
]
operations = [
migrations.AlterModelOptions(
name='accesspoint',
options={'permissions': (('view_ap', 'Peut voir une borne'),)},
),
migrations.AlterModelOptions(
name='switch',
options={'permissions': (('view_switch', 'Peut voir un objet switch'),)},
),
migrations.AlterField(
model_name='port',
name='switch',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ports', to='topologie.Switch'),
preserve_default=False,
),
migrations.AlterUniqueTogether(
name='port',
unique_together=set([('switch', 'port')]),
),
migrations.AlterUniqueTogether(
name='switch',
unique_together=set([('stack', 'stack_member_id')]),
),
]

View file

@ -47,7 +47,7 @@ from django.db import IntegrityError
from django.db import transaction from django.db import transaction
from reversion import revisions as reversion from reversion import revisions as reversion
from machines.models import Interface from machines.models import Machine, Interface
class Stack(models.Model): class Stack(models.Model):
"""Un objet stack. Regrouppe des switchs en foreign key """Un objet stack. Regrouppe des switchs en foreign key
@ -109,7 +109,7 @@ class Stack(models.Model):
inférieure à l'id minimale"}) inférieure à l'id minimale"})
class Borne(Interface): class AccessPoint(Machine):
"""Define a wireless AP. Inherit from machines.interfaces """Define a wireless AP. Inherit from machines.interfaces
Definition pour une borne wifi , hérite de machines.interfaces Definition pour une borne wifi , hérite de machines.interfaces
@ -125,38 +125,38 @@ class Borne(Interface):
class Meta: class Meta:
permissions = ( permissions = (
("view_borne", "Peut voir une borne"), ("view_ap", "Peut voir une borne"),
) )
def get_instance(borne_id, *args, **kwargs): def get_instance(ap_id, *args, **kwargs):
return Borne.objects.get(pk=borne_id) return AccessPoint.objects.get(pk=ap_id)
def can_create(user_request, *args, **kwargs): def can_create(user_request, *args, **kwargs):
return user_request.has_perm('topologie.add_borne') , u"Vous n'avez pas le droit\ return user_request.has_perm('topologie.add_ap') , u"Vous n'avez pas le droit\
de créer une borne" de créer une borne"
def can_edit(self, user_request, *args, **kwargs): def can_edit(self, user_request, *args, **kwargs):
if not user_request.has_perm('topologie.change_borne'): if not user_request.has_perm('topologie.change_ap'):
return False, u"Vous n'avez pas le droit d'éditer des bornes" return False, u"Vous n'avez pas le droit d'éditer des bornes"
return True, None return True, None
def can_delete(self, user_request, *args, **kwargs): def can_delete(self, user_request, *args, **kwargs):
if not user_request.has_perm('topologie.delete_borne'): if not user_request.has_perm('topologie.delete_ap'):
return False, u"Vous n'avez pas le droit de supprimer une borne" return False, u"Vous n'avez pas le droit de supprimer une borne"
return True, None return True, None
def can_view_all(user_request, *args, **kwargs): def can_view_all(user_request, *args, **kwargs):
if not user_request.has_perm('topologie.view_borne'): if not user_request.has_perm('topologie.view_ap'):
return False, u"Vous n'avez pas le droit de voir les bornes" return False, u"Vous n'avez pas le droit de voir les bornes"
return True, None return True, None
def can_view(self, user_request, *args, **kwargs): def can_view(self, user_request, *args, **kwargs):
if not user_request.has_perm('topologie.view_borne'): if not user_request.has_perm('topologie.view_ap'):
return False, u"Vous n'avez pas le droit de voir les bornes" return False, u"Vous n'avez pas le droit de voir les bornes"
return True, None return True, None
class Switch(Interface): class Switch(Machine):
""" Definition d'un switch. Contient un nombre de ports (number), """ Definition d'un switch. Contient un nombre de ports (number),
un emplacement (location), un stack parent (optionnel, stack) un emplacement (location), un stack parent (optionnel, stack)
et un id de membre dans le stack (stack_member_id) et un id de membre dans le stack (stack_member_id)
@ -263,6 +263,9 @@ class Switch(Interface):
except IntegrityError: except IntegrityError:
ValidationError("Création d'un port existant.") ValidationError("Création d'un port existant.")
def __str__(self):
return str(self.interface_set.first())
class ModelSwitch(models.Model): class ModelSwitch(models.Model):
"""Un modèle (au sens constructeur) de switch""" """Un modèle (au sens constructeur) de switch"""
@ -416,11 +419,11 @@ class Port(models.Model):
def get_instance(port_id, *args, **kwargs): def get_instance(port_id, *args, **kwargs):
return Port.objects\ return Port.objects\
.select_related('switch__domain__extension')\
.select_related('machine_interface__domain__extension')\ .select_related('machine_interface__domain__extension')\
.select_related('machine_interface__switch')\ .select_related('machine_interface__machine__switch')\
.select_related('room')\ .select_related('room')\
.select_related('related')\ .select_related('related')\
.prefetch_related('switch__interface_set__domain__extension')\
.get(pk=port_id) .get(pk=port_id)
def can_create(user_request, *args, **kwargs): def can_create(user_request, *args, **kwargs):

View file

@ -0,0 +1,74 @@
{% 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 acl %}
<div class="table-responsive">
{% if ap_list.paginator %}
{% include "pagination.html" with list=ap_list %}
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th>{% include "buttons/sort.html" with prefix='ap' col='name' text='Borne' %}</th>
<th>{% include "buttons/sort.html" with prefix='ap' col='mac' text='Addresse mac' %}</th>
<th>{% include "buttons/sort.html" with prefix='ap' col='ip' text='Ipv4' %}</th>
<th>Commentaire</th>
<th>Localisation</th>
<th></th>
</tr>
</thead>
{% for ap in ap_list %}
<tr>
<td>{{ap.interface_set.first}}</td>
<td>{{ap.interface_set.first.mac_address}}</td>
<td>{{ap.interface_set.first.ipv4}}</td>
<td>{{ap.interface_set.first.details}}</td>
<td>{{ap.location}}</td>
<td class="text-right">
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'ap' ap.pk %}">
<i class="fa fa-history"></i>
</a>
{% can_edit ap %}
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-ap' ap.id %}">
<i class="fa fa-edit"></i>
</a>
{% acl_end %}
{% can_delete ap %}
<a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'machines:del-machine' ap.id %}">
<i class="fa fa-trash"></i>
</a>
{% acl_end %}
</td>
</tr>
{% endfor %}
</table>
{% if ap_list.paginator %}
{% include "pagination.html" with list=ap_list %}
{% endif %}
</div>

View file

@ -1,74 +0,0 @@
{% 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 acl %}
<div class="table-responsive">
{% if borne_list.paginator %}
{% include "pagination.html" with list=borne_list %}
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th>{% include "buttons/sort.html" with prefix='borne' col='name' text='Borne' %}</th>
<th>{% include "buttons/sort.html" with prefix='borne' col='mac' text='Addresse mac' %}</th>
<th>{% include "buttons/sort.html" with prefix='borne' col='ip' text='Ipv4' %}</th>
<th>Commentaire</th>
<th>Localisation</th>
<th></th>
</tr>
</thead>
{% for borne in borne_list %}
<tr>
<td>{{borne}}</td>
<td>{{borne.mac_address}}</td>
<td>{{borne.ipv4}}</td>
<td>{{borne.details}}</td>
<td>{{borne.location}}</td>
<td class="text-right">
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'borne' borne.pk %}">
<i class="fa fa-history"></i>
</a>
{% can_edit borne %}
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-borne' borne.id %}">
<i class="fa fa-edit"></i>
</a>
{% acl_end %}
{% can_delete borne %}
<a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'machines:del-interface' borne.id %}">
<i class="fa fa-trash"></i>
</a>
{% acl_end %}
</td>
</tr>
{% endfor %}
</table>
{% if borne_list.paginator %}
{% include "pagination.html" with list=borne_list %}
{% endif %}
</div>

View file

@ -49,20 +49,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{{switch}} {{switch}}
</a> </a>
</td> </td>
<td>{{switch.ipv4}}</td> <td>{{switch.interface_set.first.ipv4}}</td>
<td>{{switch.location}}</td> <td>{{switch.location}}</td>
<td>{{switch.number}}</td> <td>{{switch.number}}</td>
<td>{{switch.stack.name}}</td> <td>{{switch.stack.name}}</td>
<td>{{switch.stack_member_id}}</td> <td>{{switch.stack_member_id}}</td>
<td>{{switch.model}}</td> <td>{{switch.model}}</td>
<td>{{switch.details}}</td> <td>{{switch.interface_set.first.details}}</td>
<td class="text-right"> <td class="text-right">
{% include 'buttons/history.html' with href='topologie:history' name='switch' id=switch.pk%} {% include 'buttons/history.html' with href='topologie:history' name='switch' id=switch.pk%}
{% can_edit switch %} {% can_edit switch %}
{% include 'buttons/edit.html' with href='topologie:edit-switch' id=switch.pk %} {% include 'buttons/edit.html' with href='topologie:edit-switch' id=switch.pk %}
{% acl_end %} {% acl_end %}
{% can_delete switch %} {% can_delete switch %}
{% include 'buttons/suppr.html' with href='machines:del-interface' id=switch.id %} {% include 'buttons/suppr.html' with href='machines:del-machine' id=switch.id %}
{% acl_end %} {% acl_end %}
{% can_create Port %} {% can_create Port %}
{% include 'buttons/add.html' with href='topologie:create-ports' id=switch.pk desc='Création de ports'%} {% include 'buttons/add.html' with href='topologie:create-ports' id=switch.pk desc='Création de ports'%}

View file

@ -30,11 +30,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block content %} {% block content %}
<h2>Points d'accès WiFi</h2> <h2>Points d'accès WiFi</h2>
{% can_create Room %} {% can_create AccessPoint %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-borne' %}"><i class="fa fa-plus"></i> Ajouter une borne</a> <a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-ap' %}"><i class="fa fa-plus"></i> Ajouter une borne</a>
<hr> <hr>
{% acl_end %} {% acl_end %}
{% include "topologie/aff_borne.html" with borne_list=borne_list %} {% include "topologie/aff_ap.html" with ap_list=ap_list %}
<br /> <br />
<br /> <br />
<br /> <br />

View file

@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<i class="fa fa-microchip"></i> <i class="fa fa-microchip"></i>
Switchs Switchs
</a> </a>
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-borne" %}"> <a class="list-group-item list-group-item-info" href="{% url "topologie:index-ap" %}">
<i class="fa fa-wifi"></i> <i class="fa fa-wifi"></i>
Bornes WiFi Bornes WiFi
</a> </a>

View file

@ -35,11 +35,11 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
url(r'^index_borne/$', views.index_borne, name='index-borne'), url(r'^index_ap/$', views.index_ap, name='index-ap'),
url(r'^new_borne/$', views.new_borne, name='new-borne'), url(r'^new_ap/$', views.new_ap, name='new-ap'),
url(r'^edit_borne/(?P<borne_id>[0-9]+)$', url(r'^edit_ap/(?P<ap_id>[0-9]+)$',
views.edit_borne, views.edit_ap,
name='edit-borne'), name='edit-ap'),
url(r'^create_ports/(?P<switch_id>[0-9]+)$', url(r'^create_ports/(?P<switch_id>[0-9]+)$',
views.create_ports, views.create_ports,
name='create-ports'), name='create-ports'),

View file

@ -41,7 +41,7 @@ from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.db import IntegrityError from django.db import IntegrityError
from django.db import transaction from django.db import transaction
from django.db.models import ProtectedError from django.db.models import ProtectedError, Prefetch
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from reversion import revisions as reversion from reversion import revisions as reversion
@ -54,7 +54,7 @@ from topologie.models import (
Stack, Stack,
ModelSwitch, ModelSwitch,
ConstructorSwitch, ConstructorSwitch,
Borne AccessPoint
) )
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
from topologie.forms import ( from topologie.forms import (
@ -64,8 +64,8 @@ from topologie.forms import (
EditModelSwitchForm, EditModelSwitchForm,
EditConstructorSwitchForm, EditConstructorSwitchForm,
CreatePortsForm, CreatePortsForm,
AddBorneForm, AddAccessPointForm,
EditBorneForm EditAccessPointForm
) )
from users.views import form from users.views import form
from re2o.utils import SortTable from re2o.utils import SortTable
@ -84,6 +84,7 @@ from machines.forms import (
AddInterfaceForm AddInterfaceForm
) )
from machines.views import generate_ipv4_mbf_param from machines.views import generate_ipv4_mbf_param
from machines.models import Interface
from preferences.models import AssoOption, GeneralOption from preferences.models import AssoOption, GeneralOption
@ -92,9 +93,10 @@ from preferences.models import AssoOption, GeneralOption
def index(request): def index(request):
""" Vue d'affichage de tous les swicthes""" """ Vue d'affichage de tous les swicthes"""
switch_list = Switch.objects\ switch_list = Switch.objects\
.select_related('domain__extension')\ .prefetch_related(Prefetch(
.select_related('ipv4')\ 'interface_set',
.select_related('domain')\ queryset=Interface.objects.select_related('ipv4__ip_type__extension').select_related('domain__extension')
))\
.select_related('stack') .select_related('stack')
switch_list = SortTable.sort( switch_list = SortTable.sort(
switch_list, switch_list,
@ -127,9 +129,11 @@ def index_port(request, switch, switch_id):
.select_related('room')\ .select_related('room')\
.select_related('machine_interface__domain__extension')\ .select_related('machine_interface__domain__extension')\
.select_related('machine_interface__machine__user')\ .select_related('machine_interface__machine__user')\
.select_related( .select_related('related__switch')\
'related__switch__domain__extension' .prefetch_related(Prefetch(
)\ 'related__switch__interface_set',
queryset=Interface.objects.select_related('domain__extension')
))\
.select_related('switch') .select_related('switch')
port_list = SortTable.sort( port_list = SortTable.sort(
port_list, port_list,
@ -172,29 +176,33 @@ def index_room(request):
@login_required @login_required
@can_view_all(Borne) @can_view_all(AccessPoint)
def index_borne(request): def index_ap(request):
""" Affichage de l'ensemble des bornes""" """ Affichage de l'ensemble des bornes"""
borne_list = Borne.objects ap_list = AccessPoint.objects\
borne_list = SortTable.sort( .prefetch_related(Prefetch(
borne_list, 'interface_set',
queryset=Interface.objects.select_related('ipv4__ip_type__extension').select_related('domain__extension')
))
ap_list = SortTable.sort(
ap_list,
request.GET.get('col'), request.GET.get('col'),
request.GET.get('order'), request.GET.get('order'),
SortTable.TOPOLOGIE_INDEX_BORNE SortTable.TOPOLOGIE_INDEX_BORNE
) )
pagination_number = GeneralOption.get_cached_value('pagination_number') pagination_number = GeneralOption.get_cached_value('pagination_number')
paginator = Paginator(borne_list, pagination_number) paginator = Paginator(ap_list, pagination_number)
page = request.GET.get('page') page = request.GET.get('page')
try: try:
borne_list = paginator.page(page) ap_list = paginator.page(page)
except PageNotAnInteger: except PageNotAnInteger:
# If page is not an integer, deliver first page. # If page is not an integer, deliver first page.
borne_list = paginator.page(1) ap_list = paginator.page(1)
except EmptyPage: except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results. # If page is out of range (e.g. 9999), deliver last page of results.
borne_list = paginator.page(paginator.num_pages) ap_list = paginator.page(paginator.num_pages)
return render(request, 'topologie/index_borne.html', { return render(request, 'topologie/index_ap.html', {
'borne_list': borne_list 'ap_list': ap_list
}) })
@ -385,45 +393,45 @@ def new_switch(request):
request.POST or None, request.POST or None,
user=request.user user=request.user
) )
machine = NewMachineForm( interface = AddInterfaceForm(
request.POST or None, request.POST or None,
user=request.user user=request.user
) )
domain = DomainForm( domain = DomainForm(
request.POST or None, request.POST or None,
) )
if switch.is_valid() and machine.is_valid(): if switch.is_valid() and interface.is_valid():
user = AssoOption.get_cached_value('utilisateur_asso') user = AssoOption.get_cached_value('utilisateur_asso')
if not user: if not user:
messages.error(request, "L'user association n'existe pas encore,\ messages.error(request, "L'user association n'existe pas encore,\
veuillez le créer ou le linker dans preferences") veuillez le créer ou le linker dans preferences")
return redirect(reverse('topologie:index')) return redirect(reverse('topologie:index'))
new_machine = machine.save(commit=False) new_switch = switch.save(commit=False)
new_machine.user = user new_switch.user = user
new_switch_instance = switch.save(commit=False) new_interface_instance = interface.save(commit=False)
domain.instance.interface_parent = new_switch_instance domain.instance.interface_parent = new_interface_instance
if domain.is_valid(): if domain.is_valid():
new_domain_instance = domain.save(commit=False) new_domain_instance = domain.save(commit=False)
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_machine.save() new_switch.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
new_switch_instance.machine = new_machine new_interface_instance.machine = new_switch
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_switch_instance.save() new_interface_instance.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
new_domain_instance.interface_parent = new_switch_instance new_domain_instance.interface_parent = new_interface_instance
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_domain_instance.save() new_domain_instance.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Le switch a été créé") messages.success(request, "Le switch a été créé")
return redirect(reverse('topologie:index')) return redirect(reverse('topologie:index'))
i_mbf_param = generate_ipv4_mbf_param(switch, False) i_mbf_param = generate_ipv4_mbf_param(interface, False)
return form({ return form({
'topoform': switch, 'topoform': interface,
'machineform': machine, 'machineform': switch,
'domainform': domain, 'domainform': domain,
'i_mbf_param': i_mbf_param, 'i_mbf_param': i_mbf_param,
'device' : 'switch', 'device' : 'switch',
@ -479,32 +487,32 @@ def edit_switch(request, switch, switch_id):
instance=switch, instance=switch,
user=request.user user=request.user
) )
machine_form = EditMachineForm( interface_form = EditInterfaceForm(
request.POST or None, request.POST or None,
instance=switch.machine, instance=switch.interface_set.first(),
user=request.user user=request.user
) )
domain_form = DomainForm( domain_form = DomainForm(
request.POST or None, request.POST or None,
instance=switch.domain instance=switch.interface_set.first().domain
) )
if switch_form.is_valid() and machine_form.is_valid(): if switch_form.is_valid() and interface_form.is_valid():
new_machine = machine_form.save(commit=False) new_switch = switch_form.save(commit=False)
new_switch_instance = switch_form.save(commit=False) new_interface_instance = interface_form.save(commit=False)
new_domain = domain_form.save(commit=False) new_domain = domain_form.save(commit=False)
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_machine.save() new_switch.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment( reversion.set_comment(
"Champs modifié(s) : %s" % ', '.join( "Champs modifié(s) : %s" % ', '.join(
field for field in machine_form.changed_data field for field in switch_form.changed_data
) )
) )
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_switch_instance.save() new_interface_instance.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join( reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
field for field in switch_form.changed_data) field for field in interface_form.changed_data)
) )
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_domain.save() new_domain.save()
@ -514,11 +522,11 @@ def edit_switch(request, switch, switch_id):
) )
messages.success(request, "Le switch a bien été modifié") messages.success(request, "Le switch a bien été modifié")
return redirect(reverse('topologie:index')) return redirect(reverse('topologie:index'))
i_mbf_param = generate_ipv4_mbf_param(switch_form, False ) i_mbf_param = generate_ipv4_mbf_param(interface_form, False )
return form({ return form({
'id_switch': switch_id, 'id_switch': switch_id,
'topoform': switch_form, 'topoform': interface_form,
'machineform': machine_form, 'machineform': switch_form,
'domainform': domain_form, 'domainform': domain_form,
'i_mbf_param': i_mbf_param, 'i_mbf_param': i_mbf_param,
'device' : 'switch', 'device' : 'switch',
@ -526,54 +534,54 @@ def edit_switch(request, switch, switch_id):
@login_required @login_required
@can_create(Borne) @can_create(AccessPoint)
def new_borne(request): def new_ap(request):
""" Creation d'une borne. Cree en meme temps l'interface et la machine """ Creation d'une ap. Cree en meme temps l'interface et la machine
associée. Vue complexe. Appelle successivement les 3 models forms associée. Vue complexe. Appelle successivement les 3 models forms
adaptés : machine, interface, domain et switch""" adaptés : machine, interface, domain et switch"""
borne = AddBorneForm( ap = AddAccessPointForm(
request.POST or None, request.POST or None,
user=request.user user=request.user
) )
machine = NewMachineForm( interface = AddInterfaceForm(
request.POST or None, request.POST or None,
user=request.user user=request.user
) )
domain = DomainForm( domain = DomainForm(
request.POST or None, request.POST or None,
) )
if borne.is_valid() and machine.is_valid(): if ap.is_valid() and interface.is_valid():
user = AssoOption.get_cached_value('utilisateur_asso') user = AssoOption.get_cached_value('utilisateur_asso')
if not user: if not user:
messages.error(request, "L'user association n'existe pas encore,\ messages.error(request, "L'user association n'existe pas encore,\
veuillez le créer ou le linker dans preferences") veuillez le créer ou le linker dans preferences")
return redirect(reverse('topologie:index')) return redirect(reverse('topologie:index'))
new_machine = machine.save(commit=False) new_ap = ap.save(commit=False)
new_machine.user = user new_ap.user = user
new_borne = borne.save(commit=False) new_interface = interface.save(commit=False)
domain.instance.interface_parent = new_borne domain.instance.interface_parent = new_interface
if domain.is_valid(): if domain.is_valid():
new_domain_instance = domain.save(commit=False) new_domain_instance = domain.save(commit=False)
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_machine.save() new_ap.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
new_borne.machine = new_machine new_interface.machine = new_ap
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_borne.save() new_interface.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
new_domain_instance.interface_parent = new_borne new_domain_instance.interface_parent = new_interface
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_domain_instance.save() new_domain_instance.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "La borne a été créé") messages.success(request, "La borne a été créé")
return redirect(reverse('topologie:index-borne')) return redirect(reverse('topologie:index-ap'))
i_mbf_param = generate_ipv4_mbf_param(borne, False) i_mbf_param = generate_ipv4_mbf_param(interface, False)
return form({ return form({
'topoform': borne, 'topoform': interface,
'machineform': machine, 'machineform': ap,
'domainform': domain, 'domainform': domain,
'i_mbf_param': i_mbf_param, 'i_mbf_param': i_mbf_param,
'device' : 'wifi ap', 'device' : 'wifi ap',
@ -581,45 +589,45 @@ def new_borne(request):
@login_required @login_required
@can_edit(Borne) @can_edit(AccessPoint)
def edit_borne(request, borne, borne_id): def edit_ap(request, ap, ap_id):
""" Edition d'un switch. Permet de chambre nombre de ports, """ Edition d'un switch. Permet de chambre nombre de ports,
place dans le stack, interface et machine associée""" place dans le stack, interface et machine associée"""
borne_form = EditBorneForm( interface_form = EditInterfaceForm(
request.POST or None, request.POST or None,
user=request.user, user=request.user,
instance=borne instance=ap.interface_set.first()
) )
machine_form = NewMachineForm( ap_form = EditAccessPointForm(
request.POST or None, request.POST or None,
user=request.user, user=request.user,
instance=borne.machine instance=ap
) )
domain_form = DomainForm( domain_form = DomainForm(
request.POST or None, request.POST or None,
instance=borne.domain instance=ap.interface_set.first().domain
) )
if borne_form.is_valid() and machine_form.is_valid(): if ap_form.is_valid() and interface_form.is_valid():
user = AssoOption.get_cached_value('utilisateur_asso') user = AssoOption.get_cached_value('utilisateur_asso')
if not user: if not user:
messages.error(request, "L'user association n'existe pas encore,\ messages.error(request, "L'user association n'existe pas encore,\
veuillez le créer ou le linker dans preferences") veuillez le créer ou le linker dans preferences")
return redirect(reverse('topologie:index-borne')) return redirect(reverse('topologie:index-ap'))
new_machine = machine_form.save(commit=False) new_ap = ap_form.save(commit=False)
new_borne = borne_form.save(commit=False) new_interface = interface_form.save(commit=False)
new_domain = domain_form.save(commit=False) new_domain = domain_form.save(commit=False)
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_machine.save() new_ap.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment( reversion.set_comment(
"Champs modifié(s) : %s" % ', '.join( "Champs modifié(s) : %s" % ', '.join(
field for field in machine_form.changed_data) field for field in ap_form.changed_data)
) )
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
new_borne.save() new_interface.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join( reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
field for field in borne_form.changed_data) field for field in interface_form.changed_data)
) )
reversion.set_comment("Création") reversion.set_comment("Création")
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
@ -629,11 +637,11 @@ def edit_borne(request, borne, borne_id):
field for field in domain_form.changed_data) field for field in domain_form.changed_data)
) )
messages.success(request, "La borne a été modifiée") messages.success(request, "La borne a été modifiée")
return redirect(reverse('topologie:index-borne')) return redirect(reverse('topologie:index-ap'))
i_mbf_param = generate_ipv4_mbf_param(borne_form, False ) i_mbf_param = generate_ipv4_mbf_param(interface_form, False )
return form({ return form({
'topoform': borne_form, 'topoform': interface_form,
'machineform': machine_form, 'machineform': ap_form,
'domainform': domain_form, 'domainform': domain_form,
'i_mbf_param': i_mbf_param, 'i_mbf_param': i_mbf_param,
'device' : 'wifi ap', 'device' : 'wifi ap',

View file

@ -501,8 +501,7 @@ def del_school(request, instances):
@login_required @login_required
@can_create(ListShell) @can_create(ListShell)
def add_shell(request): def add_shell(request):
""" Ajouter un établissement d'enseignement à la base de donnée, """ Ajouter un shell à la base de donnée"""
need cableur"""
shell = ShellForm(request.POST or None) shell = ShellForm(request.POST or None)
if shell.is_valid(): if shell.is_valid():
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
@ -517,8 +516,7 @@ def add_shell(request):
@login_required @login_required
@can_edit(ListShell) @can_edit(ListShell)
def edit_shell(request, shell_instance, shellid): def edit_shell(request, shell_instance, shellid):
""" Editer un établissement d'enseignement à partir du shellid dans """ Editer un shell à partir du shellid"""
la base de donnée, need cableur"""
shell = ShellForm(request.POST or None, instance=shell_instance) shell = ShellForm(request.POST or None, instance=shell_instance)
if shell.is_valid(): if shell.is_valid():
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():