mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-26 06:32:26 +00:00
Serialisation des roles et réglages par vlan des switches
This commit is contained in:
parent
aa53816dd2
commit
47ad76ed20
10 changed files with 211 additions and 10 deletions
|
@ -153,7 +153,7 @@ class VlanSerializer(NamespacedHMSerializer):
|
||||||
"""
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = machines.Vlan
|
model = machines.Vlan
|
||||||
fields = ('vlan_id', 'name', 'comment', 'api_url')
|
fields = ('vlan_id', 'name', 'comment', 'arp_protect', 'dhcp_snooping', 'dhcpv6_snooping', 'api_url')
|
||||||
|
|
||||||
|
|
||||||
class NasSerializer(NamespacedHMSerializer):
|
class NasSerializer(NamespacedHMSerializer):
|
||||||
|
@ -303,6 +303,16 @@ class OuverturePortSerializer(NamespacedHMSerializer):
|
||||||
fields = ('begin', 'end', 'port_list', 'protocole', 'io', 'api_url')
|
fields = ('begin', 'end', 'port_list', 'protocole', 'io', 'api_url')
|
||||||
|
|
||||||
|
|
||||||
|
class RoleSerializer(NamespacedHMSerializer):
|
||||||
|
"""Serialize `machines.models.OuverturePort` objects.
|
||||||
|
"""
|
||||||
|
servers = InterfaceSerializer(read_only=True, many=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = machines.Role
|
||||||
|
fields = ('role_type', 'servers', 'api_url')
|
||||||
|
|
||||||
|
|
||||||
# PREFERENCES
|
# PREFERENCES
|
||||||
|
|
||||||
|
|
||||||
|
@ -634,6 +644,34 @@ class ServiceRegenSerializer(NamespacedHMSerializer):
|
||||||
|
|
||||||
# Switches et ports
|
# Switches et ports
|
||||||
|
|
||||||
|
class InterfaceVlanSerializer(NamespacedHMSerializer):
|
||||||
|
domain = serializers.CharField(read_only=True)
|
||||||
|
ipv4 = serializers.CharField(read_only=True)
|
||||||
|
ipv6 = Ipv6ListSerializer(read_only=True, many=True)
|
||||||
|
vlan_id = serializers.IntegerField(source='type.ip_type.vlan.vlan_id', read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = machines.Interface
|
||||||
|
fields = ('ipv4', 'ipv6', 'domain', 'vlan_id')
|
||||||
|
|
||||||
|
class InterfaceRoleSerializer(NamespacedHMSerializer):
|
||||||
|
interface = InterfaceVlanSerializer(source='machine.interface_set', read_only=True, many=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = machines.Interface
|
||||||
|
fields = ('interface',)
|
||||||
|
|
||||||
|
|
||||||
|
class RoleSerializer(NamespacedHMSerializer):
|
||||||
|
"""Serialize `machines.models.OuverturePort` objects.
|
||||||
|
"""
|
||||||
|
servers = InterfaceRoleSerializer(read_only=True, many=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = machines.Role
|
||||||
|
fields = ('role_type', 'servers')
|
||||||
|
|
||||||
|
|
||||||
class VlanPortSerializer(NamespacedHMSerializer):
|
class VlanPortSerializer(NamespacedHMSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = machines.Vlan
|
model = machines.Vlan
|
||||||
|
@ -669,7 +707,7 @@ class PortsSerializer(NamespacedHMSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = topologie.Port
|
model = topologie.Port
|
||||||
fields = ('state', 'port', 'get_port_profil')
|
fields = ('state', 'port', 'pretty_name', 'get_port_profil')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -682,7 +720,7 @@ class SwitchPortSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = topologie.Switch
|
model = topologie.Switch
|
||||||
fields = ('short_name', 'model', 'switchbay', 'ports', 'subnet', 'subnet6')
|
fields = ('short_name', 'model', 'switchbay', 'ports', 'ipv4', 'ipv6', 'subnet', 'subnet6')
|
||||||
|
|
||||||
# DHCP
|
# DHCP
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ router.register_viewset(r'machines/service', views.ServiceViewSet)
|
||||||
router.register_viewset(r'machines/servicelink', views.ServiceLinkViewSet, base_name='servicelink')
|
router.register_viewset(r'machines/servicelink', views.ServiceLinkViewSet, base_name='servicelink')
|
||||||
router.register_viewset(r'machines/ouvertureportlist', views.OuverturePortListViewSet)
|
router.register_viewset(r'machines/ouvertureportlist', views.OuverturePortListViewSet)
|
||||||
router.register_viewset(r'machines/ouvertureport', views.OuverturePortViewSet)
|
router.register_viewset(r'machines/ouvertureport', views.OuverturePortViewSet)
|
||||||
|
router.register_viewset(r'machines/role', views.RoleViewSet)
|
||||||
# PREFERENCES
|
# PREFERENCES
|
||||||
router.register_view(r'preferences/optionaluser', views.OptionalUserView),
|
router.register_view(r'preferences/optionaluser', views.OptionalUserView),
|
||||||
router.register_view(r'preferences/optionalmachine', views.OptionalMachineView),
|
router.register_view(r'preferences/optionalmachine', views.OptionalMachineView),
|
||||||
|
@ -100,6 +101,7 @@ router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name=
|
||||||
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
||||||
# Switches config
|
# Switches config
|
||||||
router.register_view(r'switchs/ports-config', views.SwitchPortView),
|
router.register_view(r'switchs/ports-config', views.SwitchPortView),
|
||||||
|
router.register_view(r'switchs/role', views.RoleView),
|
||||||
# Reminder
|
# Reminder
|
||||||
router.register_view(r'reminder/get-users', views.ReminderView),
|
router.register_view(r'reminder/get-users', views.ReminderView),
|
||||||
# DNS
|
# DNS
|
||||||
|
|
16
api/views.py
16
api/views.py
|
@ -234,6 +234,13 @@ class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
serializer_class = serializers.OuverturePortSerializer
|
serializer_class = serializers.OuverturePortSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
|
"""Exposes list and details of `machines.models.Machine` objects.
|
||||||
|
"""
|
||||||
|
queryset = machines.Role.objects.all()
|
||||||
|
serializer_class = serializers.RoleSerializer
|
||||||
|
|
||||||
|
|
||||||
# PREFERENCES
|
# PREFERENCES
|
||||||
# Those views differ a bit because there is only one object
|
# Those views differ a bit because there is only one object
|
||||||
# to display, so we don't bother with the listing part
|
# to display, so we don't bother with the listing part
|
||||||
|
@ -504,6 +511,15 @@ class SwitchPortView(generics.ListAPIView):
|
||||||
queryset = topologie.Switch.objects.all().prefetch_related('ports__custom_profile')
|
queryset = topologie.Switch.objects.all().prefetch_related('ports__custom_profile')
|
||||||
serializer_class = serializers.SwitchPortSerializer
|
serializer_class = serializers.SwitchPortSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class RoleView(generics.ListAPIView):
|
||||||
|
"""Exposes the associations between hostname, mac address and IPv4 in
|
||||||
|
order to build the DHCP lease files.
|
||||||
|
"""
|
||||||
|
queryset = machines.Role.objects.all().prefetch_related('servers')
|
||||||
|
serializer_class = serializers.RoleSerializer
|
||||||
|
|
||||||
|
|
||||||
# Rappel fin adhésion
|
# Rappel fin adhésion
|
||||||
|
|
||||||
class ReminderView(generics.ListAPIView):
|
class ReminderView(generics.ListAPIView):
|
||||||
|
|
30
machines/migrations/0091_auto_20180707_2040.py
Normal file
30
machines/migrations/0091_auto_20180707_2040.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2018-07-07 18:40
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('machines', '0090_auto_20180625_1706'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vlan',
|
||||||
|
name='arp_protect',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vlan',
|
||||||
|
name='dhcp_snooping',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vlan',
|
||||||
|
name='dhcpv6_snooping',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
|
@ -387,6 +387,8 @@ class IpType(RevMixin, AclMixin, models.Model):
|
||||||
'network': str(ip_set.network),
|
'network': str(ip_set.network),
|
||||||
'netmask': str(ip_set.netmask),
|
'netmask': str(ip_set.netmask),
|
||||||
'broadcast': str(ip_set.broadcast),
|
'broadcast': str(ip_set.broadcast),
|
||||||
|
'vlan': str(self.vlan),
|
||||||
|
'vlan_id': self.vlan.vlan_id
|
||||||
} for ip_set in self.ip_set.iter_cidrs()
|
} for ip_set in self.ip_set.iter_cidrs()
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -395,7 +397,9 @@ class IpType(RevMixin, AclMixin, models.Model):
|
||||||
if self.prefix_v6:
|
if self.prefix_v6:
|
||||||
return {
|
return {
|
||||||
'network' : str(self.prefix_v6),
|
'network' : str(self.prefix_v6),
|
||||||
'netmask' : 'ffff:ffff:ffff:ffff::'
|
'netmask' : 'ffff:ffff:ffff:ffff::',
|
||||||
|
'vlan': str(self.vlan),
|
||||||
|
'vlan_id': str(self.vlan.vlan_id)
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
@ -494,6 +498,10 @@ class Vlan(RevMixin, AclMixin, models.Model):
|
||||||
vlan_id = models.PositiveIntegerField(validators=[MaxValueValidator(4095)])
|
vlan_id = models.PositiveIntegerField(validators=[MaxValueValidator(4095)])
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
comment = models.CharField(max_length=256, blank=True)
|
comment = models.CharField(max_length=256, blank=True)
|
||||||
|
#Réglages supplémentaires
|
||||||
|
arp_protect = models.BooleanField(default=False)
|
||||||
|
dhcp_snooping = models.BooleanField(default=False)
|
||||||
|
dhcpv6_snooping = models.BooleanField(default=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
|
|
|
@ -271,6 +271,14 @@ class Switch(AclMixin, Machine):
|
||||||
""" Returns the 'main' interface of the switch """
|
""" Returns the 'main' interface of the switch """
|
||||||
return self.interface_set.first()
|
return self.interface_set.first()
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def ipv4(self):
|
||||||
|
return str(self.main_interface().ipv4)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def ipv6(self):
|
||||||
|
return str(self.main_interface().ipv6().first())
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def subnet(self):
|
def subnet(self):
|
||||||
return self.main_interface().type.ip_type.ip_set_full_info
|
return self.main_interface().type.ip_type.ip_set_full_info
|
||||||
|
@ -414,6 +422,18 @@ class Port(AclMixin, RevMixin, models.Model):
|
||||||
("view_port", "Peut voir un objet port"),
|
("view_port", "Peut voir un objet port"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def pretty_name(self):
|
||||||
|
"""More elaborated name for label on switch conf"""
|
||||||
|
if self.related:
|
||||||
|
return "Uplink : " + self.related.switch.short_name
|
||||||
|
elif self.machine_interface:
|
||||||
|
return "Machine : " + str(self.machine_interface.domain)
|
||||||
|
elif self.room:
|
||||||
|
return "Chambre : " + str(self.room)
|
||||||
|
else:
|
||||||
|
return "Inconnue"
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def get_port_profil(self):
|
def get_port_profil(self):
|
||||||
"""Return the config profil for this port
|
"""Return the config profil for this port
|
||||||
|
|
55
topologie/templates/topologie/aff_vlanoptions.html
Normal file
55
topologie/templates/topologie/aff_vlanoptions.html
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{% 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">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Nom</th>
|
||||||
|
<th>Arp Protect</th>
|
||||||
|
<th>Dhcp Snooping</th>
|
||||||
|
<th>Dhcpv6 Snooping</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for vlan in vlan_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ vlan.vlan_id }}</td>
|
||||||
|
<td>{{ vlan.name }}</td>
|
||||||
|
<td>{{ vlan.arp_protect }}</td>
|
||||||
|
<td>{{ vlan.dhcp_snooping }}</td>
|
||||||
|
<td>{{ vlan.dhcpv6_snooping }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% can_edit vlan %}
|
||||||
|
{% include 'buttons/edit.html' with href='topologie:edit-vlanoptions' id=vlan.id %}
|
||||||
|
{% acl_end %}
|
||||||
|
{% include 'buttons/history.html' with href='machines:history' name='vlan' id=vlan.id %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
|
@ -30,12 +30,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
<h2>{% trans "Port profiles" %}</h2>
|
<h2>{% trans "Port profiles" %}</h2>
|
||||||
{% can_create PortProfile %}
|
{% 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>
|
<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>
|
<hr>
|
||||||
{% acl_end %}
|
{% acl_end %}
|
||||||
{% include "topologie/aff_port_profile.html" with port_profile_list=port_profile_list %}
|
{% include "topologie/aff_port_profile.html" with port_profile_list=port_profile_list %}
|
||||||
|
|
||||||
|
|
||||||
|
<h2>{% trans "Sécurité par vlan" %}</h2>
|
||||||
|
{% include "topologie/aff_vlanoptions.html" with vlan_list=vlan_list %}
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -125,4 +125,7 @@ urlpatterns = [
|
||||||
url(r'^del_port_profile/(?P<portprofileid>[0-9]+)$',
|
url(r'^del_port_profile/(?P<portprofileid>[0-9]+)$',
|
||||||
views.del_port_profile,
|
views.del_port_profile,
|
||||||
name='del-port-profile'),
|
name='del-port-profile'),
|
||||||
|
url(r'^edit_vlanoptions/(?P<vlanid>[0-9]+)$',
|
||||||
|
views.edit_vlanoptions,
|
||||||
|
name='edit-vlanoptions'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -64,10 +64,15 @@ from re2o.settings import MEDIA_ROOT
|
||||||
from machines.forms import (
|
from machines.forms import (
|
||||||
DomainForm,
|
DomainForm,
|
||||||
EditInterfaceForm,
|
EditInterfaceForm,
|
||||||
AddInterfaceForm
|
AddInterfaceForm,
|
||||||
|
EditOptionVlanForm
|
||||||
)
|
)
|
||||||
from machines.views import generate_ipv4_mbf_param
|
from machines.views import generate_ipv4_mbf_param
|
||||||
from machines.models import Interface, Service_link
|
from machines.models import (
|
||||||
|
Interface,
|
||||||
|
Service_link,
|
||||||
|
Vlan
|
||||||
|
)
|
||||||
from preferences.models import AssoOption, GeneralOption
|
from preferences.models import AssoOption, GeneralOption
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
|
@ -152,10 +157,11 @@ def index_port_profile(request):
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
||||||
port_profile_list = PortProfile.objects.all().select_related('vlan_untagged')
|
port_profile_list = PortProfile.objects.all().select_related('vlan_untagged')
|
||||||
port_profile_list = re2o_paginator(request, port_profile_list, pagination_number)
|
port_profile_list = re2o_paginator(request, port_profile_list, pagination_number)
|
||||||
|
vlan_list = Vlan.objects.all().order_by('vlan_id')
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
'topologie/index_portprofile.html',
|
'topologie/index_portprofile.html',
|
||||||
{'port_profile_list': port_profile_list}
|
{'port_profile_list': port_profile_list, 'vlan_list': vlan_list}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,6 +312,23 @@ def index_model_switch(request):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_edit(Vlan)
|
||||||
|
def edit_vlanoptions(request, vlan_instance, **_kwargs):
|
||||||
|
""" View used to edit options for switch of VLAN object """
|
||||||
|
vlan = EditOptionVlanForm(request.POST or None, instance=vlan_instance)
|
||||||
|
if vlan.is_valid():
|
||||||
|
if vlan.changed_data:
|
||||||
|
vlan.save()
|
||||||
|
messages.success(request, "Vlan modifié")
|
||||||
|
return redirect(reverse('topologie:index-port-profile'))
|
||||||
|
return form(
|
||||||
|
{'vlanform': vlan, 'action_name': 'Editer'},
|
||||||
|
'machines/machine.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_create(Port)
|
@can_create(Port)
|
||||||
def new_port(request, switchid):
|
def new_port(request, switchid):
|
||||||
|
|
Loading…
Reference in a new issue