mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-25 00:13:45 +00:00
Merge branch 'borne_object' into 'master'
Borne object See merge request nounous/re2o!6
This commit is contained in:
commit
1c2fb2b728
15 changed files with 559 additions and 8 deletions
|
@ -233,6 +233,12 @@ class SortTable:
|
||||||
'room_name': ['name'],
|
'room_name': ['name'],
|
||||||
'default': ['name']
|
'default': ['name']
|
||||||
}
|
}
|
||||||
|
TOPOLOGIE_INDEX_BORNE = {
|
||||||
|
'borne_name': ['domain__name'],
|
||||||
|
'borne_ip': ['ipv4__ipv4'],
|
||||||
|
'borne_mac': ['mac_address'],
|
||||||
|
'default': ['domain__name']
|
||||||
|
}
|
||||||
TOPOLOGIE_INDEX_STACK = {
|
TOPOLOGIE_INDEX_STACK = {
|
||||||
'stack_name': ['name'],
|
'stack_name': ['name'],
|
||||||
'stack_id': ['stack_id'],
|
'stack_id': ['stack_id'],
|
||||||
|
|
|
@ -82,6 +82,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,
|
||||||
},
|
},
|
||||||
'machines' : {
|
'machines' : {
|
||||||
'machine' : machines.models.Machine,
|
'machine' : machines.models.Machine,
|
||||||
|
|
|
@ -29,7 +29,15 @@ from __future__ import unicode_literals
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from reversion.admin import VersionAdmin
|
from reversion.admin import VersionAdmin
|
||||||
|
|
||||||
from .models import Port, Room, Switch, Stack, ModelSwitch, ConstructorSwitch
|
from .models import (
|
||||||
|
Port,
|
||||||
|
Room,
|
||||||
|
Switch,
|
||||||
|
Stack,
|
||||||
|
ModelSwitch,
|
||||||
|
ConstructorSwitch,
|
||||||
|
Borne
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StackAdmin(VersionAdmin):
|
class StackAdmin(VersionAdmin):
|
||||||
|
@ -47,6 +55,11 @@ class PortAdmin(VersionAdmin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BorneAdmin(VersionAdmin):
|
||||||
|
"""Administration d'une borne"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class RoomAdmin(VersionAdmin):
|
class RoomAdmin(VersionAdmin):
|
||||||
"""Administration d'un chambre"""
|
"""Administration d'un chambre"""
|
||||||
pass
|
pass
|
||||||
|
@ -63,6 +76,7 @@ class ConstructorSwitchAdmin(VersionAdmin):
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Port, PortAdmin)
|
admin.site.register(Port, PortAdmin)
|
||||||
|
admin.site.register(Borne, BorneAdmin)
|
||||||
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)
|
||||||
|
|
|
@ -33,9 +33,18 @@ 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 django import forms
|
from django import forms
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from .models import Port, Switch, Room, Stack, ModelSwitch, ConstructorSwitch
|
from .models import (
|
||||||
|
Port,
|
||||||
|
Switch,
|
||||||
|
Room,
|
||||||
|
Stack,
|
||||||
|
ModelSwitch,
|
||||||
|
ConstructorSwitch,
|
||||||
|
Borne
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class PortForm(ModelForm):
|
class PortForm(ModelForm):
|
||||||
|
@ -102,6 +111,21 @@ class StackForm(ModelForm):
|
||||||
super(StackForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(StackForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class AddBorneForm(EditInterfaceForm):
|
||||||
|
"""Formulaire pour la création d'une borne
|
||||||
|
Relié directement au modèle borne"""
|
||||||
|
class Meta:
|
||||||
|
model = Borne
|
||||||
|
fields = ['mac_address', 'type', 'ipv4', 'details', 'location']
|
||||||
|
|
||||||
|
|
||||||
|
class EditBorneForm(EditInterfaceForm):
|
||||||
|
"""Edition d'une interface. Edition complète"""
|
||||||
|
class Meta:
|
||||||
|
model = Borne
|
||||||
|
fields = ['machine', 'type', 'ipv4', 'mac_address', 'details', 'location']
|
||||||
|
|
||||||
|
|
||||||
class EditSwitchForm(ModelForm):
|
class EditSwitchForm(ModelForm):
|
||||||
"""Permet d'éditer un switch : nom et nombre de ports"""
|
"""Permet d'éditer un switch : nom et nombre de ports"""
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
47
topologie/management/commands/sync_unifi_ap.py
Normal file
47
topologie/management/commands/sync_unifi_ap.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# ⁻*- mode: python; coding: utf-8 -*-
|
||||||
|
# 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 © 2018 Gabriel Detraz
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from pymongo import MongoClient
|
||||||
|
from topologie.models import Borne
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Ce script donne un nom aux bornes dans le controleur unifi.
|
||||||
|
A lancer sur le serveur en local où se trouve le controleur'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
# Connexion mongodb
|
||||||
|
client = MongoClient("mongodb://localhost:27117")
|
||||||
|
db = client.ace
|
||||||
|
device = db['device']
|
||||||
|
|
||||||
|
bornes = Borne.objects.all()
|
||||||
|
|
||||||
|
def set_bornes_names(liste_bornes):
|
||||||
|
"""Met à jour les noms des bornes dans la bdd du controleur"""
|
||||||
|
for borne in liste_bornes:
|
||||||
|
if borne.ipv4 and borne.domain:
|
||||||
|
device.find_one_and_update({'ip': str(borne.ipv4)}, {'$set': {'name': str(borne.domain.name)}})
|
||||||
|
return
|
||||||
|
|
||||||
|
set_bornes_names(bornes)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('Mise à jour de la base de donnée unifi avec succès'))
|
28
topologie/migrations/0034_borne.py
Normal file
28
topologie/migrations/0034_borne.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# -*- 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 = [
|
||||||
|
('machines', '0076_auto_20180130_1623'),
|
||||||
|
('topologie', '0033_auto_20171231_1743'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Borne',
|
||||||
|
fields=[
|
||||||
|
('interface_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='machines.Interface')),
|
||||||
|
('location', models.CharField(help_text="Détails sur la localisation de l'AP", max_length=255)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'permissions': (('view_borne', 'Peut voir une borne'),),
|
||||||
|
},
|
||||||
|
bases=('machines.interface',),
|
||||||
|
),
|
||||||
|
]
|
20
topologie/migrations/0035_auto_20180324_0023.py
Normal file
20
topologie/migrations/0035_auto_20180324_0023.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2018-03-23 23:23
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0034_borne'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='borne',
|
||||||
|
name='location',
|
||||||
|
field=models.CharField(blank=True, help_text="Détails sur la localisation de l'AP", max_length=255, null=True),
|
||||||
|
),
|
||||||
|
]
|
32
topologie/migrations/0036_transferborne.py
Normal file
32
topologie/migrations/0036_transferborne.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# -*- 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', '0035_auto_20180324_0023'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def transfer_bornes(apps, schema_editor):
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
machinetype = apps.get_model("machines", "MachineType")
|
||||||
|
borne = apps.get_model("topologie", "Borne")
|
||||||
|
interface = apps.get_model("machines", "Interface")
|
||||||
|
bornes_list = machinetype.objects.using(db_alias).filter(type__icontains='borne')
|
||||||
|
if bornes_list:
|
||||||
|
for inter in interface.objects.using(db_alias).filter(type=bornes_list.first()):
|
||||||
|
borne_object = borne()
|
||||||
|
borne_object.interface_ptr_id = inter.pk
|
||||||
|
borne_object.__dict__.update(inter.__dict__)
|
||||||
|
borne_object.save()
|
||||||
|
|
||||||
|
def untransfer_bornes(apps, schema_editor):
|
||||||
|
return
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(transfer_bornes, untransfer_bornes),
|
||||||
|
]
|
|
@ -47,6 +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
|
||||||
|
|
||||||
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
|
||||||
|
@ -108,6 +109,53 @@ class Stack(models.Model):
|
||||||
inférieure à l'id minimale"})
|
inférieure à l'id minimale"})
|
||||||
|
|
||||||
|
|
||||||
|
class Borne(Interface):
|
||||||
|
"""Define a wireless AP. Inherit from machines.interfaces
|
||||||
|
|
||||||
|
Definition pour une borne wifi , hérite de machines.interfaces
|
||||||
|
"""
|
||||||
|
PRETTY_NAME = "Borne WiFi"
|
||||||
|
|
||||||
|
location = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
help_text="Détails sur la localisation de l'AP",
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
permissions = (
|
||||||
|
("view_borne", "Peut voir une borne"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_instance(borne_id, *args, **kwargs):
|
||||||
|
return Borne.objects.get(pk=borne_id)
|
||||||
|
|
||||||
|
def can_create(user_request, *args, **kwargs):
|
||||||
|
return user_request.has_perm('topologie.add_borne') , u"Vous n'avez pas le droit\
|
||||||
|
de créer une borne"
|
||||||
|
|
||||||
|
def can_edit(self, user_request, *args, **kwargs):
|
||||||
|
if not user_request.has_perm('topologie.change_borne'):
|
||||||
|
return False, u"Vous n'avez pas le droit d'éditer des bornes"
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
def can_delete(self, user_request, *args, **kwargs):
|
||||||
|
if not user_request.has_perm('topologie.delete_borne'):
|
||||||
|
return False, u"Vous n'avez pas le droit de supprimer une borne"
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
def can_view_all(user_request, *args, **kwargs):
|
||||||
|
if not user_request.has_perm('topologie.view_borne'):
|
||||||
|
return False, u"Vous n'avez pas le droit de voir les bornes"
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
def can_view(self, user_request, *args, **kwargs):
|
||||||
|
if not user_request.has_perm('topologie.view_borne'):
|
||||||
|
return False, u"Vous n'avez pas le droit de voir les bornes"
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
|
||||||
class Switch(models.Model):
|
class Switch(models.Model):
|
||||||
""" 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)
|
||||||
|
@ -192,6 +240,7 @@ class Switch(models.Model):
|
||||||
else:
|
else:
|
||||||
raise ValidationError({'stack_member_id': "L'id dans la stack\
|
raise ValidationError({'stack_member_id': "L'id dans la stack\
|
||||||
ne peut être nul"})
|
ne peut être nul"})
|
||||||
|
|
||||||
def create_ports(self, begin, end):
|
def create_ports(self, begin, end):
|
||||||
""" Crée les ports de begin à end si les valeurs données sont cohérentes. """
|
""" Crée les ports de begin à end si les valeurs données sont cohérentes. """
|
||||||
|
|
||||||
|
|
74
topologie/templates/topologie/aff_borne.html
Normal file
74
topologie/templates/topologie/aff_borne.html
Normal 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 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>
|
63
topologie/templates/topologie/borne.html
Normal file
63
topologie/templates/topologie/borne.html
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
{% extends "topologie/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 %}
|
||||||
|
{% load massive_bootstrap_form %}
|
||||||
|
|
||||||
|
{% block title %}Création et modification d'une borne{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if topoform %}
|
||||||
|
{% bootstrap_form_errors topoform %}
|
||||||
|
{% endif %}
|
||||||
|
{% if machineform %}
|
||||||
|
{% bootstrap_form_errors machineform %}
|
||||||
|
{% endif %}
|
||||||
|
{% if domainform %}
|
||||||
|
{% bootstrap_form_errors domainform %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<form class="form" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% if topoform %}
|
||||||
|
<h3>Réglage spécifiques de la borne</h3>
|
||||||
|
{% massive_bootstrap_form topoform 'ipv4,machine' mbf_param=i_mbf_param%}
|
||||||
|
{% endif %}
|
||||||
|
{% if machineform %}
|
||||||
|
<h3>Réglages généraux de la machine associée à la borne</h3>
|
||||||
|
{% massive_bootstrap_form machineform 'user' %}
|
||||||
|
{% endif %}
|
||||||
|
{% if domainform %}
|
||||||
|
<h3>Nom de la machine</h3>
|
||||||
|
{% bootstrap_form domainform %}
|
||||||
|
{% endif %}
|
||||||
|
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="ok" %}
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
41
topologie/templates/topologie/index_borne.html
Normal file
41
topologie/templates/topologie/index_borne.html
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{% extends "topologie/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 %}
|
||||||
|
{% load acl %}
|
||||||
|
|
||||||
|
{% block title %}Bornes WiFi{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Points d'accès WiFi</h2>
|
||||||
|
{% can_create Room %}
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-borne' %}"><i class="fa fa-plus"></i> Ajouter une borne</a>
|
||||||
|
<hr>
|
||||||
|
{% acl_end %}
|
||||||
|
{% include "topologie/aff_borne.html" with borne_list=borne_list %}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
|
@ -26,12 +26,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-room" %}">
|
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-room" %}">
|
||||||
<i class="fa fa-list-ul"></i>
|
<i class="fa fa-home"></i>
|
||||||
Chambres
|
Chambres et locaux
|
||||||
</a>
|
</a>
|
||||||
<a class="list-group-item list-group-item-info" href="{% url "topologie:index" %}">
|
<a class="list-group-item list-group-item-info" href="{% url "topologie:index" %}">
|
||||||
<i class="fa fa-list-ul"></i>
|
<i class="fa fa-microchip"></i>
|
||||||
Switchs
|
Switchs
|
||||||
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-borne" %}">
|
||||||
|
<i class="fa fa-wifi"></i>
|
||||||
|
Bornes WiFi
|
||||||
</a>
|
</a>
|
||||||
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-stack" %}">
|
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-stack" %}">
|
||||||
<i class="fa fa-list-ul"></i>
|
<i class="fa fa-list-ul"></i>
|
||||||
|
|
|
@ -35,7 +35,11 @@ from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.index, name='index'),
|
url(r'^$', views.index, name='index'),
|
||||||
url(r'^new_switch/$', views.new_switch, name='new-switch'),
|
url(r'^index_borne/$', views.index_borne, name='index-borne'),
|
||||||
|
url(r'^new_borne/$', views.new_borne, name='new-borne'),
|
||||||
|
url(r'^edit_borne/(?P<borne_id>[0-9]+)$',
|
||||||
|
views.edit_borne,
|
||||||
|
name='edit-borne'),
|
||||||
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'),
|
||||||
|
@ -43,6 +47,7 @@ urlpatterns = [
|
||||||
url(r'^new_room/$', views.new_room, name='new-room'),
|
url(r'^new_room/$', views.new_room, name='new-room'),
|
||||||
url(r'^edit_room/(?P<room_id>[0-9]+)$', views.edit_room, name='edit-room'),
|
url(r'^edit_room/(?P<room_id>[0-9]+)$', views.edit_room, name='edit-room'),
|
||||||
url(r'^del_room/(?P<room_id>[0-9]+)$', views.del_room, name='del-room'),
|
url(r'^del_room/(?P<room_id>[0-9]+)$', views.del_room, name='del-room'),
|
||||||
|
url(r'^new_switch/$', views.new_switch, name='new-switch'),
|
||||||
url(r'^switch/(?P<switch_id>[0-9]+)$',
|
url(r'^switch/(?P<switch_id>[0-9]+)$',
|
||||||
views.index_port,
|
views.index_port,
|
||||||
name='index-port'),
|
name='index-port'),
|
||||||
|
|
|
@ -53,7 +53,8 @@ from topologie.models import (
|
||||||
Room,
|
Room,
|
||||||
Stack,
|
Stack,
|
||||||
ModelSwitch,
|
ModelSwitch,
|
||||||
ConstructorSwitch
|
ConstructorSwitch,
|
||||||
|
Borne
|
||||||
)
|
)
|
||||||
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
|
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
|
||||||
from topologie.forms import (
|
from topologie.forms import (
|
||||||
|
@ -62,7 +63,9 @@ from topologie.forms import (
|
||||||
StackForm,
|
StackForm,
|
||||||
EditModelSwitchForm,
|
EditModelSwitchForm,
|
||||||
EditConstructorSwitchForm,
|
EditConstructorSwitchForm,
|
||||||
CreatePortsForm
|
CreatePortsForm,
|
||||||
|
AddBorneForm,
|
||||||
|
EditBorneForm
|
||||||
)
|
)
|
||||||
from users.views import form
|
from users.views import form
|
||||||
from re2o.utils import SortTable
|
from re2o.utils import SortTable
|
||||||
|
@ -168,6 +171,33 @@ def index_room(request):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_view_all(Borne)
|
||||||
|
def index_borne(request):
|
||||||
|
""" Affichage de l'ensemble des bornes"""
|
||||||
|
borne_list = Borne.objects
|
||||||
|
borne_list = SortTable.sort(
|
||||||
|
borne_list,
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.TOPOLOGIE_INDEX_BORNE
|
||||||
|
)
|
||||||
|
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
||||||
|
paginator = Paginator(borne_list, pagination_number)
|
||||||
|
page = request.GET.get('page')
|
||||||
|
try:
|
||||||
|
borne_list = paginator.page(page)
|
||||||
|
except PageNotAnInteger:
|
||||||
|
# If page is not an integer, deliver first page.
|
||||||
|
borne_list = paginator.page(1)
|
||||||
|
except EmptyPage:
|
||||||
|
# If page is out of range (e.g. 9999), deliver last page of results.
|
||||||
|
borne_list = paginator.page(paginator.num_pages)
|
||||||
|
return render(request, 'topologie/index_borne.html', {
|
||||||
|
'borne_list': borne_list
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_view_all(Stack)
|
@can_view_all(Stack)
|
||||||
def index_stack(request):
|
def index_stack(request):
|
||||||
|
@ -510,6 +540,119 @@ def edit_switch(request, switch, switch_id):
|
||||||
}, 'topologie/switch.html', request)
|
}, 'topologie/switch.html', request)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_create(Borne)
|
||||||
|
def new_borne(request):
|
||||||
|
""" Creation d'une borne. Cree en meme temps l'interface et la machine
|
||||||
|
associée. Vue complexe. Appelle successivement les 3 models forms
|
||||||
|
adaptés : machine, interface, domain et switch"""
|
||||||
|
borne = AddBorneForm(
|
||||||
|
request.POST or None,
|
||||||
|
user=request.user
|
||||||
|
)
|
||||||
|
machine = NewMachineForm(
|
||||||
|
request.POST or None,
|
||||||
|
user=request.user
|
||||||
|
)
|
||||||
|
domain = DomainForm(
|
||||||
|
request.POST or None,
|
||||||
|
)
|
||||||
|
if borne.is_valid() and machine.is_valid():
|
||||||
|
user = AssoOption.get_cached_value('utilisateur_asso')
|
||||||
|
if not user:
|
||||||
|
messages.error(request, "L'user association n'existe pas encore,\
|
||||||
|
veuillez le créer ou le linker dans preferences")
|
||||||
|
return redirect(reverse('topologie:index'))
|
||||||
|
new_machine = machine.save(commit=False)
|
||||||
|
new_machine.user = user
|
||||||
|
new_borne = borne.save(commit=False)
|
||||||
|
domain.instance.interface_parent = new_borne
|
||||||
|
if domain.is_valid():
|
||||||
|
new_domain_instance = domain.save(commit=False)
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
new_machine.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Création")
|
||||||
|
new_borne.machine = new_machine
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
new_borne.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Création")
|
||||||
|
new_domain_instance.interface_parent = new_borne
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
new_domain_instance.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Création")
|
||||||
|
messages.success(request, "La borne a été créé")
|
||||||
|
return redirect(reverse('topologie:index-borne'))
|
||||||
|
i_mbf_param = generate_ipv4_mbf_param(borne, False)
|
||||||
|
return form({
|
||||||
|
'topoform': borne,
|
||||||
|
'machineform': machine,
|
||||||
|
'domainform': domain,
|
||||||
|
'i_mbf_param': i_mbf_param
|
||||||
|
}, 'topologie/borne.html', request)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_edit(Borne)
|
||||||
|
def edit_borne(request, borne, borne_id):
|
||||||
|
""" Edition d'un switch. Permet de chambre nombre de ports,
|
||||||
|
place dans le stack, interface et machine associée"""
|
||||||
|
borne_form = EditBorneForm(
|
||||||
|
request.POST or None,
|
||||||
|
user=request.user,
|
||||||
|
instance=borne
|
||||||
|
)
|
||||||
|
machine_form = NewMachineForm(
|
||||||
|
request.POST or None,
|
||||||
|
user=request.user,
|
||||||
|
instance=borne.machine
|
||||||
|
)
|
||||||
|
domain_form = DomainForm(
|
||||||
|
request.POST or None,
|
||||||
|
instance=borne.domain
|
||||||
|
)
|
||||||
|
if borne_form.is_valid() and machine_form.is_valid():
|
||||||
|
user = AssoOption.get_cached_value('utilisateur_asso')
|
||||||
|
if not user:
|
||||||
|
messages.error(request, "L'user association n'existe pas encore,\
|
||||||
|
veuillez le créer ou le linker dans preferences")
|
||||||
|
return redirect(reverse('topologie:index-borne'))
|
||||||
|
new_machine = machine_form.save(commit=False)
|
||||||
|
new_borne = borne_form.save(commit=False)
|
||||||
|
new_domain = domain_form.save(commit=False)
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
new_machine.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment(
|
||||||
|
"Champs modifié(s) : %s" % ', '.join(
|
||||||
|
field for field in machine_form.changed_data)
|
||||||
|
)
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
new_borne.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
||||||
|
field for field in borne_form.changed_data)
|
||||||
|
)
|
||||||
|
reversion.set_comment("Création")
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
new_domain.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
|
||||||
|
field for field in domain_form.changed_data)
|
||||||
|
)
|
||||||
|
messages.success(request, "La borne a été modifiée")
|
||||||
|
return redirect(reverse('topologie:index-borne'))
|
||||||
|
i_mbf_param = generate_ipv4_mbf_param(borne_form, False )
|
||||||
|
return form({
|
||||||
|
'topoform': borne_form,
|
||||||
|
'machineform': machine_form,
|
||||||
|
'domainform': domain_form,
|
||||||
|
'i_mbf_param': i_mbf_param
|
||||||
|
}, 'topologie/borne.html', request)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_create(Room)
|
@can_create(Room)
|
||||||
def new_room(request):
|
def new_room(request):
|
||||||
|
|
Loading…
Reference in a new issue