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

add model PortProfile

This commit is contained in:
Laouen Fernet 2018-05-27 00:36:25 +02:00 committed by Hugo LEVY-FALK
parent ea7ea032f0
commit 0ed68194d7
12 changed files with 390 additions and 4 deletions

View file

@ -37,7 +37,6 @@ from django.views.decorators.cache import cache_page
from preferences.models import (
Service,
MailContact,
GeneralOption,
AssoOption,
HomeOption
)
@ -108,6 +107,7 @@ def about_page(request):
}
)
def contact_page(request):
"""The view for the contact page
Send all the objects MailContact

View file

@ -38,7 +38,8 @@ from .models import (
ConstructorSwitch,
AccessPoint,
SwitchBay,
Building
Building,
PortProfile,
)
@ -86,6 +87,9 @@ class BuildingAdmin(VersionAdmin):
"""Administration d'un batiment"""
pass
class PortProfileAdmin(VersionAdmin):
"""Administration of a port profile"""
pass
admin.site.register(Port, PortAdmin)
admin.site.register(AccessPoint, AccessPointAdmin)
@ -96,3 +100,4 @@ admin.site.register(ModelSwitch, ModelSwitchAdmin)
admin.site.register(ConstructorSwitch, ConstructorSwitchAdmin)
admin.site.register(Building, BuildingAdmin)
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.forms import ModelForm
from django.db.models import Prefetch
from django.utils.translation import ugettext_lazy as _
from machines.models import Interface
from machines.forms import (
@ -53,6 +54,7 @@ from .models import (
AccessPoint,
SwitchBay,
Building,
PortProfile,
)
@ -254,3 +256,59 @@ class EditBuildingForm(FormRevMixin, ModelForm):
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
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.db import IntegrityError
from django.db import transaction
from django.utils.translation import ugettext_lazy as _
from reversion import revisions as reversion
from machines.models import Machine, regen
@ -492,6 +493,60 @@ class Room(AclMixin, RevMixin, models.Model):
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)
def ap_post_save(**_kwargs):
"""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 acl %}
{% load i18n %}
{% block title %}Switchs{% endblock %}
@ -72,5 +73,14 @@ Topologie des Switchs
<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 %}

View file

@ -108,4 +108,13 @@ urlpatterns = [
url(r'^del_building/(?P<buildingid>[0-9]+)$',
views.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.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import ugettext as _
import tempfile
@ -80,6 +81,7 @@ from .models import (
SwitchBay,
Building,
Server,
PortProfile,
)
from .forms import (
EditPortForm,
@ -94,7 +96,9 @@ from .forms import (
AddAccessPointForm,
EditAccessPointForm,
EditSwitchBayForm,
EditBuildingForm
EditBuildingForm,
NewPortProfileForm,
EditPortProfileForm,
)
from subprocess import (
@ -124,8 +128,12 @@ def index(request):
request.GET.get('order'),
SortTable.TOPOLOGIE_INDEX
)
port_profile_list = PortProfile.objects.all()
pagination_number = GeneralOption.get_cached_value('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')):
make_machine_graph()
@ -137,7 +145,7 @@ def index(request):
return render(
request,
'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)
@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():
"""
Create the graph of switchs, machines and access points.