diff --git a/re2o/utils.py b/re2o/utils.py index 5abe0c33..a3de2a89 100644 --- a/re2o/utils.py +++ b/re2o/utils.py @@ -233,6 +233,11 @@ class SortTable: 'room_name': ['name'], 'default': ['name'] } + TOPOLOGIE_INDEX_BORNE = { + 'borne_name': ['domain__name'], + 'borne_ipv4': ['borne__ipv4__ipv4'], + 'default': ['domain__name'] + } TOPOLOGIE_INDEX_STACK = { 'stack_name': ['name'], 'stack_id': ['stack_id'], diff --git a/re2o/views.py b/re2o/views.py index bfb2e6c5..2beb1636 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -82,6 +82,7 @@ HISTORY_BIND = { 'stack' : topologie.models.Stack, 'model_switch' : topologie.models.ModelSwitch, 'constructor_switch' : topologie.models.ConstructorSwitch, + 'borne' : topologie.models.Borne, }, 'machines' : { 'machine' : machines.models.Machine, diff --git a/topologie/admin.py b/topologie/admin.py index a4591222..f7021148 100644 --- a/topologie/admin.py +++ b/topologie/admin.py @@ -29,7 +29,15 @@ from __future__ import unicode_literals from django.contrib import admin 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): @@ -47,6 +55,11 @@ class PortAdmin(VersionAdmin): pass +class BorneAdmin(VersionAdmin): + """Administration d'une borne""" + pass + + class RoomAdmin(VersionAdmin): """Administration d'un chambre""" pass @@ -63,6 +76,7 @@ class ConstructorSwitchAdmin(VersionAdmin): admin.site.register(Port, PortAdmin) +admin.site.register(Borne, BorneAdmin) admin.site.register(Room, RoomAdmin) admin.site.register(Switch, SwitchAdmin) admin.site.register(Stack, StackAdmin) diff --git a/topologie/forms.py b/topologie/forms.py index c4c369a6..42572fe7 100644 --- a/topologie/forms.py +++ b/topologie/forms.py @@ -33,9 +33,18 @@ NewSwitchForm) from __future__ import unicode_literals from machines.models import Interface +from machines.forms import EditInterfaceForm from django import forms 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): @@ -102,6 +111,21 @@ class StackForm(ModelForm): 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): """Permet d'éditer un switch : nom et nombre de ports""" class Meta: diff --git a/topologie/management/commands/sync_unifi_ap.py b/topologie/management/commands/sync_unifi_ap.py new file mode 100644 index 00000000..532aa5d5 --- /dev/null +++ b/topologie/management/commands/sync_unifi_ap.py @@ -0,0 +1,41 @@ +# ⁻*- 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 + +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'] + + def set_bornes_names(liste_bornes): + """Met à jour les noms des bornes dans la bdd du controleur""" + for borne in liste_bornes: + device.find_one_and_update({'ip': str(borne['ipHostNumber'][0])}, {'$set': {'name': borne['host'][0].split('.')[0]}}) + return + + self.stdout.write(self.style.SUCCESS('Mise à jour de la base de donnée unifi avec succès')) diff --git a/topologie/migrations/0034_borne.py b/topologie/migrations/0034_borne.py new file mode 100644 index 00000000..6d827f3a --- /dev/null +++ b/topologie/migrations/0034_borne.py @@ -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',), + ), + ] diff --git a/topologie/migrations/0035_auto_20180324_0023.py b/topologie/migrations/0035_auto_20180324_0023.py new file mode 100644 index 00000000..7fa69d01 --- /dev/null +++ b/topologie/migrations/0035_auto_20180324_0023.py @@ -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), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index 0871b402..5c48773f 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -47,6 +47,7 @@ from django.db import IntegrityError from django.db import transaction from reversion import revisions as reversion +from machines.models import Interface class Stack(models.Model): """Un objet stack. Regrouppe des switchs en foreign key @@ -108,6 +109,53 @@ class Stack(models.Model): 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): """ Definition d'un switch. Contient un nombre de ports (number), un emplacement (location), un stack parent (optionnel, stack) @@ -192,6 +240,7 @@ class Switch(models.Model): else: raise ValidationError({'stack_member_id': "L'id dans la stack\ ne peut être nul"}) + def create_ports(self, begin, end): """ Crée les ports de begin à end si les valeurs données sont cohérentes. """ diff --git a/topologie/templates/topologie/aff_borne.html b/topologie/templates/topologie/aff_borne.html new file mode 100644 index 00000000..8080aaaf --- /dev/null +++ b/topologie/templates/topologie/aff_borne.html @@ -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 %} + +
{% include "buttons/sort.html" with prefix='borne' col='name' text='Borne' %} | +{% include "buttons/sort.html" with prefix='borne' col='mac' text='Addresse mac' %} | +{% include "buttons/sort.html" with prefix='borne' col='ip' text='Ipv4' %} | +Commentaire | +Localisation | ++ |
---|---|---|---|---|---|
{{borne}} | +{{borne.mac_address}} | +{{borne.ipv4}} | +{{borne.details}} | +{{borne.location}} | ++ + + + {% can_edit borne %} + + + + {% acl_end %} + {% can_delete borne %} + + + + {% acl_end %} + | +