8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-08-19 13:43:40 +00:00

Merge branch 'switch_conf_json' of https://gitlab.federez.net/federez/re2o into switch_conf_json

This commit is contained in:
root 2018-06-26 15:23:38 +00:00
commit adc5757f51
13 changed files with 391 additions and 3 deletions

View file

@ -129,6 +129,7 @@ MODEL_NAME = {
'Room': topologie.models.Room, 'Room': topologie.models.Room,
'Building': topologie.models.Building, 'Building': topologie.models.Building,
'SwitchBay': topologie.models.SwitchBay, 'SwitchBay': topologie.models.SwitchBay,
'PortProfile': topologie.models.PortProfile,
# users # users
'User': users.models.User, 'User': users.models.User,
'Adherent': users.models.Adherent, 'Adherent': users.models.Adherent,

View file

@ -111,6 +111,7 @@ HISTORY_BIND = {
'accesspoint': topologie.models.AccessPoint, 'accesspoint': topologie.models.AccessPoint,
'switchbay': topologie.models.SwitchBay, 'switchbay': topologie.models.SwitchBay,
'building': topologie.models.Building, 'building': topologie.models.Building,
'portprofile': topologie.models.PortProfile,
}, },
'machines': { 'machines': {
'machine': machines.models.Machine, 'machine': machines.models.Machine,

View file

@ -38,7 +38,8 @@ from .models import (
ConstructorSwitch, ConstructorSwitch,
AccessPoint, AccessPoint,
SwitchBay, SwitchBay,
Building Building,
PortProfile,
) )
@ -86,6 +87,9 @@ class BuildingAdmin(VersionAdmin):
"""Administration d'un batiment""" """Administration d'un batiment"""
pass pass
class PortProfileAdmin(VersionAdmin):
"""Administration of a port profile"""
pass
admin.site.register(Port, PortAdmin) admin.site.register(Port, PortAdmin)
admin.site.register(AccessPoint, AccessPointAdmin) admin.site.register(AccessPoint, AccessPointAdmin)
@ -96,3 +100,4 @@ admin.site.register(ModelSwitch, ModelSwitchAdmin)
admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin) admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin)
admin.site.register(Building, BuildingAdmin) admin.site.register(Building, BuildingAdmin)
admin.site.register(SwitchBay, SwitchBayAdmin) admin.site.register(SwitchBay, SwitchBayAdmin)
admin.site.register(PortProfile, PortProfileAdmin)

View file

@ -35,6 +35,7 @@ from __future__ import unicode_literals
from django import forms from django import forms
from django.forms import ModelForm from django.forms import ModelForm
from django.db.models import Prefetch from django.db.models import Prefetch
from django.utils.translation import ugettext_lazy as _
from machines.models import Interface from machines.models import Interface
from machines.forms import ( from machines.forms import (
@ -53,6 +54,7 @@ from .models import (
AccessPoint, AccessPoint,
SwitchBay, SwitchBay,
Building, Building,
PortProfile,
) )
@ -262,3 +264,59 @@ class EditBuildingForm(FormRevMixin, ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EditBuildingForm, self).__init__(*args, prefix=prefix, **kwargs) super(EditBuildingForm, self).__init__(*args, prefix=prefix, **kwargs)
class NewPortProfileForm(FormRevMixin, ModelForm):
"""Form to create a port profile"""
class Meta:
model = PortProfile
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(NewPortProfileForm, self).__init__(*args,
prefix=prefix,
**kwargs)
def clean(self):
cleaned_data = super(NewPortProfileForm, self).clean()
radius_type = cleaned_data.get('radius_type')
radius_mode = cleaned_data.get('radius_mode')
if radius_type == 'NO' and radius_mode:
raise forms.ValidationError(_("You can't specify a RADIUS mode"
" with RADIUS type NO"))
elif radius_type != 'NO' and not radius_mode:
raise forms.ValidationError(_("You have to specify a RADIUS"
" mode"))
return cleaned_data
class EditPortProfileForm(FormRevMixin, ModelForm):
"""Form to edit a port profile"""
class Meta:
model = PortProfile
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EditPortProfileForm, self).__init__(*args,
prefix=prefix,
**kwargs)
def clean(self):
cleaned_data = super(EditPortProfileForm, self).clean()
radius_type = cleaned_data.get('radius_type')
radius_mode = cleaned_data.get('radius_mode')
if radius_type == 'NO' and radius_mode:
raise forms.ValidationError(_("You can't specify a RADIUS mode"
" with RADIUS type NO"))
elif radius_type != 'NO' and not radius_mode:
raise forms.ValidationError(_("You have to specify a RADIUS"
" mode"))
return cleaned_data

View file

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-05-26 22:26
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import re2o.mixins
class Migration(migrations.Migration):
dependencies = [
('machines', '0081_auto_20180521_1413'),
('topologie', '0060_server'),
]
operations = [
migrations.CreateModel(
name='PortProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('room_default', models.BooleanField()),
('hotspot_default', models.BooleanField()),
('uplink_default', models.BooleanField()),
('orga_machine_default', models.BooleanField()),
('radius_type', models.CharField(choices=[('NO', 'NO'), ('802.1X', '802.1X'), ('MAC-radius', 'MAC-radius')], max_length=32)),
('radius_mode', models.CharField(choices=[('STRICT', 'STRICT'), ('COMMON', 'COMMON')], max_length=32)),
('vlan_tagged', models.ManyToManyField(related_name='vlan_tagged', to='machines.Vlan')),
('vlan_untagged', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlan_untagged', to='machines.Vlan')),
],
options={
'permissions': (('view_port_profile', 'Can view a port profile object'),),
},
bases=(re2o.mixins.AclMixin, models.Model),
),
]

View file

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-09 16:51
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('topologie', '0061_portprofile'),
]
operations = [
migrations.AlterModelOptions(
name='portprofile',
options={'permissions': (('view_port_profile', 'Can view a port profile object'),), 'verbose_name': 'Port profile', 'verbose_name_plural': 'Port profiles'},
),
migrations.AddField(
model_name='portprofile',
name='name',
field=models.CharField(default='Sans nom', max_length=255, verbose_name='Name'),
preserve_default=False,
),
migrations.AlterField(
model_name='portprofile',
name='hotspot_default',
field=models.BooleanField(verbose_name='Hotspot default'),
),
migrations.AlterField(
model_name='portprofile',
name='orga_machine_default',
field=models.BooleanField(verbose_name='Organisation machine default'),
),
migrations.AlterField(
model_name='portprofile',
name='radius_mode',
field=models.CharField(choices=[('STRICT', 'STRICT'), ('COMMON', 'COMMON')], max_length=32, verbose_name='RADIUS mode'),
),
migrations.AlterField(
model_name='portprofile',
name='radius_type',
field=models.CharField(choices=[('NO', 'NO'), ('802.1X', '802.1X'), ('MAC-radius', 'MAC-radius')], max_length=32, verbose_name='RADIUS type'),
),
migrations.AlterField(
model_name='portprofile',
name='room_default',
field=models.BooleanField(verbose_name='Room default'),
),
migrations.AlterField(
model_name='portprofile',
name='uplink_default',
field=models.BooleanField(verbose_name='Uplink default'),
),
migrations.AlterField(
model_name='portprofile',
name='vlan_tagged',
field=models.ManyToManyField(related_name='vlan_tagged', to='machines.Vlan', verbose_name='VLAN(s) tagged'),
),
migrations.AlterField(
model_name='portprofile',
name='vlan_untagged',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlan_untagged', to='machines.Vlan', verbose_name='VLAN untagged'),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-09 16:58
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('topologie', '0062_auto_20180609_1151'),
]
operations = [
migrations.AlterField(
model_name='portprofile',
name='vlan_tagged',
field=models.ManyToManyField(blank=True, related_name='vlan_tagged', to='machines.Vlan', verbose_name='VLAN(s) tagged'),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-09 17:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('topologie', '0063_auto_20180609_1158'),
]
operations = [
migrations.AlterField(
model_name='portprofile',
name='radius_mode',
field=models.CharField(blank=True, choices=[('STRICT', 'STRICT'), ('COMMON', 'COMMON')], max_length=32, null=True, verbose_name='RADIUS mode'),
),
]

View file

@ -46,6 +46,7 @@ from django.dispatch import receiver
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import IntegrityError from django.db import IntegrityError
from django.db import transaction from django.db import transaction
from django.utils.translation import ugettext_lazy as _
from reversion import revisions as reversion from reversion import revisions as reversion
from machines.models import Machine, regen from machines.models import Machine, regen
@ -488,6 +489,60 @@ class Room(AclMixin, RevMixin, models.Model):
return self.name return self.name
class PortProfile(AclMixin, models.Model):
"""Contains the information of the ports' configuration for a switch"""
TYPES = (
('NO', 'NO'),
('802.1X', '802.1X'),
('MAC-radius', 'MAC-radius'),
)
MODES = (
('STRICT', 'STRICT'),
('COMMON', 'COMMON'),
)
name = models.CharField(max_length=255, verbose_name=_("Name"))
room_default = models.BooleanField(verbose_name=_("Room default"))
hotspot_default = models.BooleanField(_("Hotspot default"))
uplink_default = models.BooleanField(_("Uplink default"))
orga_machine_default = models.BooleanField(_("Organisation machine"
" default"))
vlan_untagged = models.ForeignKey(
'machines.Vlan',
related_name='vlan_untagged',
on_delete=models.SET_NULL,
blank=True,
null=True,
verbose_name=_("VLAN untagged")
)
vlan_tagged = models.ManyToManyField(
'machines.Vlan',
related_name='vlan_tagged',
blank=True,
verbose_name=_("VLAN(s) tagged"))
radius_type = models.CharField(
max_length=32,
choices=TYPES,
verbose_name=_("RADIUS type")
)
radius_mode = models.CharField(
max_length=32,
choices=MODES,
blank=True,
null=True,
verbose_name=_("RADIUS mode")
)
class Meta:
permissions = (
("view_port_profile", _("Can view a port profile object")),
)
verbose_name = _("Port profile")
verbose_name_plural = _("Port profiles")
def __str__(self):
return self.name
@receiver(post_save, sender=AccessPoint) @receiver(post_save, sender=AccessPoint)
def ap_post_save(**_kwargs): def ap_post_save(**_kwargs):
"""Regeneration des noms des bornes vers le controleur""" """Regeneration des noms des bornes vers le controleur"""

View file

@ -0,0 +1,46 @@
{% load acl %}
{% load i18n %}
<div class="table-responsive">
{% if port_profile_list.paginator %}
{% include "pagination.html" with list=port_profile_list %}
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "Name" %}</th>
<th>{% trans "VLAN untagged" %}</th>
<th>{% trans "VLAN(s) tagged" %}</th>
<th>{% trans "RADIUS type" %}</th>
<th>{% trans "RADIUS mode" %}</th>
</tr>
</thead>
{% for port_profile in port_profile_list %}
<tr>
<td>{{port_profile.name}}</td>
<td>{{port_profile.vlan_untagged}}</td>
<td>
{{port_profile.vlan_tagged.all|join:", "}}
</td>
<td>{{port_profile.radius_type}}</td>
<td>{{port_profile.radius_mode}}</td>
<td class="text-right">
{% include 'buttons/history.html' with href='topologie:history' name='portprofile' id=port_profile.pk %}
{% can_edit port_profile %}
{% include 'buttons/edit.html' with href='topologie:edit-port-profile' id=port_profile.pk %}
{% acl_end %}
{% can_delete port_profile %}
{% include 'buttons/suppr.html' with href='topologie:del-port-profile' id=port_profile.pk %}
{% acl_end %}
</td>
</tr>
{% endfor %}
</table>
{% if port_profile_list.paginator %}
{% include "pagination.html" with list=port_profile_list %}
{% endif %}
</div>

View file

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load bootstrap3 %} {% load bootstrap3 %}
{% load acl %} {% load acl %}
{% load i18n %}
{% block title %}Switchs{% endblock %} {% block title %}Switchs{% endblock %}
@ -72,5 +73,14 @@ Topologie des Switchs
<br /> <br />
<br /> <br />
<h2>{% trans "Port profiles" %}</h2>
{% can_create PortProfile %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-port-profile' %}"><i class="fa fa-plus"></i>{% trans " Add a port profile" %}</a>
<hr>
{% acl_end %}
{% include "topologie/aff_port_profile.html" with port_profile_list=port_profile_list %}
<br />
<br />
<br />
{% endblock %} {% endblock %}

View file

@ -113,4 +113,13 @@ urlpatterns = [
url(r'^del_building/(?P<buildingid>[0-9]+)$', url(r'^del_building/(?P<buildingid>[0-9]+)$',
views.del_building, views.del_building,
name='del-building'), name='del-building'),
url(r'^new_port_profile/$',
views.new_port_profile,
name='new-port-profile'),
url(r'^edit_port_profile/(?P<portprofileid>[0-9]+)$',
views.edit_port_profile,
name='edit-port-profile'),
url(r'^del_port_profile/(?P<portprofileid>[0-9]+)$',
views.del_port_profile,
name='del-port-profile'),
] ]

View file

@ -47,6 +47,7 @@ from django.template.loader import get_template
from django.template import Context, Template, loader from django.template import Context, Template, loader
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.translation import ugettext as _
import tempfile import tempfile
@ -80,6 +81,7 @@ from .models import (
SwitchBay, SwitchBay,
Building, Building,
Server, Server,
PortProfile,
) )
from .forms import ( from .forms import (
EditPortForm, EditPortForm,
@ -94,7 +96,9 @@ from .forms import (
AddAccessPointForm, AddAccessPointForm,
EditAccessPointForm, EditAccessPointForm,
EditSwitchBayForm, EditSwitchBayForm,
EditBuildingForm EditBuildingForm,
NewPortProfileForm,
EditPortProfileForm,
) )
from subprocess import ( from subprocess import (
@ -124,8 +128,12 @@ def index(request):
request.GET.get('order'), request.GET.get('order'),
SortTable.TOPOLOGIE_INDEX SortTable.TOPOLOGIE_INDEX
) )
port_profile_list = PortProfile.objects.all()
pagination_number = GeneralOption.get_cached_value('pagination_number') pagination_number = GeneralOption.get_cached_value('pagination_number')
switch_list = re2o_paginator(request, switch_list, pagination_number) switch_list = re2o_paginator(request, switch_list, pagination_number)
port_profile_list = re2o_paginator(request, port_profile_list, pagination_number)
if any(service_link.need_regen() for service_link in Service_link.objects.filter(service__service_type='graph_topo')): if any(service_link.need_regen() for service_link in Service_link.objects.filter(service__service_type='graph_topo')):
make_machine_graph() make_machine_graph()
@ -137,7 +145,7 @@ def index(request):
return render( return render(
request, request,
'topologie/index.html', 'topologie/index.html',
{'switch_list': switch_list} {'switch_list': switch_list, 'port_profile_list': port_profile_list}
) )
@ -955,6 +963,59 @@ def del_constructor_switch(request, constructor_switch, **_kwargs):
}, 'topologie/delete.html', request) }, 'topologie/delete.html', request)
@login_required
@can_create(PortProfile)
def new_port_profile(request):
"""Create a new port profile"""
port_profile = NewPortProfileForm(request.POST or None)
if port_profile.is_valid():
port_profile.save()
messages.success(request, _("Port profile created"))
return redirect(reverse('topologie:index'))
return form(
{'topoform': port_profile, 'action_name': _("Create")},
'topologie/topo.html',
request
)
@login_required
@can_edit(PortProfile)
def edit_port_profile(request, port_profile, **_kwargs):
"""Edit a port profile"""
port_profile = EditPortProfileForm(request.POST or None, instance=port_profile)
if port_profile.is_valid():
if port_profile.changed_data:
port_profile.save()
messages.success(request, _("Port profile modified"))
return redirect(reverse('topologie:index'))
return form(
{'topoform': port_profile, 'action_name': _("Edit")},
'topologie/topo.html',
request
)
@login_required
@can_delete(PortProfile)
def del_port_profile(request, port_profile, **_kwargs):
"""Delete a port profile"""
if request.method == 'POST':
try:
port_profile.delete()
messages.success(request, _("The port profile was successfully"
" deleted"))
except ProtectedError:
messages.success(request, _("Impossible to delete the port"
" profile"))
return redirect(reverse('topologie:index'))
return form(
{'objet': port_profile, 'objet_name': _("Port profile")},
'topologie/delete.html',
request
)
def make_machine_graph(): def make_machine_graph():
""" """
Create the graph of switchs, machines and access points. Create the graph of switchs, machines and access points.