diff --git a/machines/admin.py b/machines/admin.py
index 34880d9f..10d1b520 100644
--- a/machines/admin.py
+++ b/machines/admin.py
@@ -24,7 +24,7 @@
from django.contrib import admin
from reversion.admin import VersionAdmin
-from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Vlan, Text, Service
+from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Vlan, Text, Nas, Service
class MachineAdmin(VersionAdmin):
pass
@@ -50,6 +50,8 @@ class NsAdmin(VersionAdmin):
class TextAdmin(VersionAdmin):
pass
+class NasAdmin(VersionAdmin):
+ pass
class IpListAdmin(VersionAdmin):
pass
@@ -75,3 +77,4 @@ admin.site.register(Interface, InterfaceAdmin)
admin.site.register(Domain, DomainAdmin)
admin.site.register(Service, ServiceAdmin)
admin.site.register(Vlan, VlanAdmin)
+admin.site.register(Nas, NasAdmin)
diff --git a/machines/forms.py b/machines/forms.py
index 5a2de206..f0091c59 100644
--- a/machines/forms.py
+++ b/machines/forms.py
@@ -22,7 +22,7 @@
from django.forms import ModelForm, Form, ValidationError
from django import forms
-from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, IpType
+from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, Nas, IpType
from django.db.models import Q
from django.core.validators import validate_email
@@ -202,6 +202,14 @@ class TextForm(ModelForm):
class DelTextForm(Form):
text = forms.ModelMultipleChoiceField(queryset=Text.objects.all(), label="Enregistrements Text actuels", widget=forms.CheckboxSelectMultiple)
+class NasForm(ModelForm):
+ class Meta:
+ model = Nas
+ fields = '__all__'
+
+class DelNasForm(Form):
+ nas = forms.ModelMultipleChoiceField(queryset=Nas.objects.all(), label="Enregistrements Nas actuels", widget=forms.CheckboxSelectMultiple)
+
class ServiceForm(ModelForm):
class Meta:
model = Service
diff --git a/machines/migrations/0055_nas.py b/machines/migrations/0055_nas.py
new file mode 100644
index 00000000..9e0466ae
--- /dev/null
+++ b/machines/migrations/0055_nas.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-09-10 21:51
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('machines', '0054_text_zone'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Nas',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255, unique=True)),
+ ('machine_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='machinetype_on_nas', to='machines.MachineType')),
+ ('nas_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='nas_type', to='machines.MachineType')),
+ ],
+ ),
+ ]
diff --git a/machines/models.py b/machines/models.py
index 8e67f8f3..833c231f 100644
--- a/machines/models.py
+++ b/machines/models.py
@@ -139,6 +139,16 @@ class Vlan(models.Model):
def __str__(self):
return self.name
+class Nas(models.Model):
+ PRETTY_NAME = "Correspondance entre les nas et les machines connectées"
+
+ name = models.CharField(max_length=255, unique=True)
+ nas_type = models.ForeignKey('MachineType', on_delete=models.PROTECT, related_name='nas_type')
+ machine_type = models.ForeignKey('MachineType', on_delete=models.PROTECT, related_name='machinetype_on_nas')
+
+ def __str__(self):
+ return self.name
+
class Extension(models.Model):
PRETTY_NAME = "Extensions dns"
diff --git a/machines/templates/machines/aff_nas.html b/machines/templates/machines/aff_nas.html
new file mode 100644
index 00000000..f9aa73c8
--- /dev/null
+++ b/machines/templates/machines/aff_nas.html
@@ -0,0 +1,48 @@
+{% 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 %}
+
+
+
+
+ Nom
+ Type du nas
+ Type de machine reliées au nas
+
+
+
+ {% for nas in nas_list %}
+
+ {{ nas.name }}
+ {{ nas.nas_type }}
+ {{ nas.machine_type }}
+
+ {% if is_infra %}
+ {% include 'buttons/edit.html' with href='machines:edit-nas' id=nas.id %}
+ {% endif %}
+ {% include 'buttons/history.html' with href='machines:history' name='nas' id=nas.id %}
+
+
+ {% endfor %}
+
+
diff --git a/machines/templates/machines/index_nas.html b/machines/templates/machines/index_nas.html
new file mode 100644
index 00000000..16fb29e2
--- /dev/null
+++ b/machines/templates/machines/index_nas.html
@@ -0,0 +1,41 @@
+{% extends "machines/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 %}
+
+{% block title %}Machines{% endblock %}
+
+{% block content %}
+ Liste des nas
+ La correpondance nas-machinetype relie le type de nas à un type de machine.
+ Elle est utile pour l'autoenregistrement des macs par radius, et permet de choisir le type de machine à affecter aux machines en fonction du type de nas
+ Ajouter un type de nas
+ Supprimer un ou plusieurs types nas
+ {% include "machines/aff_nas.html" with nas_list=nas_list %}
+
+
+
+{% endblock %}
+
diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html
index 9157de08..974b7fdb 100644
--- a/machines/templates/machines/sidebar.html
+++ b/machines/templates/machines/sidebar.html
@@ -46,6 +46,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Vlans
+
+
+ Correspondances nas-machines
+
Services (dhcp, dns...)
diff --git a/machines/urls.py b/machines/urls.py
index 3f7e0ff3..3801b449 100644
--- a/machines/urls.py
+++ b/machines/urls.py
@@ -63,6 +63,10 @@ urlpatterns = [
url(r'^edit_vlan/(?P[0-9]+)$', views.edit_vlan, name='edit-vlan'),
url(r'^del_vlan/$', views.del_vlan, name='del-vlan'),
url(r'^index_vlan/$', views.index_vlan, name='index-vlan'),
+ url(r'^add_nas/$', views.add_nas, name='add-nas'),
+ url(r'^edit_nas/(?P[0-9]+)$', views.edit_nas, name='edit-nas'),
+ url(r'^del_nas/$', views.del_nas, name='del-nas'),
+ url(r'^index_nas/$', views.index_nas, name='index-nas'),
url(r'^history/(?Pmachine)/(?P[0-9]+)$', views.history, name='history'),
url(r'^history/(?Pinterface)/(?P[0-9]+)$', views.history, name='history'),
url(r'^history/(?Pmachinetype)/(?P[0-9]+)$', views.history, name='history'),
@@ -73,6 +77,7 @@ urlpatterns = [
url(r'^history/(?Piptype)/(?P[0-9]+)$', views.history, name='history'),
url(r'^history/(?Palias)/(?P[0-9]+)$', views.history, name='history'),
url(r'^history/(?Pvlan)/(?P[0-9]+)$', views.history, name='history'),
+ url(r'^history/(?Pnas)/(?P[0-9]+)$', views.history, name='history'),
url(r'^history/(?Pservice)/(?P[0-9]+)$', views.history, name='history'),
url(r'^$', views.index, name='index'),
url(r'^rest/mac-ip/$', views.mac_ip, name='mac-ip'),
diff --git a/machines/views.py b/machines/views.py
index 9347d415..d70523da 100644
--- a/machines/views.py
+++ b/machines/views.py
@@ -44,8 +44,8 @@ from reversion.models import Version
import re
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm
-from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm
-from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Text
+from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm
+from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text
from users.models import User
from users.models import all_has_access
from preferences.models import GeneralOption, OptionalMachine
@@ -677,7 +677,7 @@ def del_vlan(request):
vlan = DelVlanForm(request.POST or None)
if vlan.is_valid():
vlan_dels = vlan.cleaned_data['vlan']
- for vlan_del in ns_dels:
+ for vlan_del in vlan_dels:
try:
with transaction.atomic(), reversion.create_revision():
vlan_del.delete()
@@ -688,6 +688,54 @@ def del_vlan(request):
return redirect("/machines/index_vlan")
return form({'machineform': vlan, 'interfaceform': None}, 'machines/machine.html', request)
+@login_required
+@permission_required('infra')
+def add_nas(request):
+ nas = NasForm(request.POST or None)
+ if nas.is_valid():
+ with transaction.atomic(), reversion.create_revision():
+ nas.save()
+ reversion.set_user(request.user)
+ reversion.set_comment("Création")
+ messages.success(request, "Cet enregistrement nas a été ajouté")
+ return redirect("/machines/index_nas")
+ return form({'machineform': nas, 'interfaceform': None}, 'machines/machine.html', request)
+
+@login_required
+@permission_required('infra')
+def edit_nas(request, nasid):
+ try:
+ nas_instance = Nas.objects.get(pk=nasid)
+ except Nas.DoesNotExist:
+ messages.error(request, u"Entrée inexistante" )
+ return redirect("/machines/index_nas/")
+ nas = NasForm(request.POST or None, instance=nas_instance)
+ if nas.is_valid():
+ with transaction.atomic(), reversion.create_revision():
+ nas.save()
+ reversion.set_user(request.user)
+ reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in nas.changed_data))
+ messages.success(request, "Nas modifié")
+ return redirect("/machines/index_nas/")
+ return form({'machineform': nas}, 'machines/machine.html', request)
+
+@login_required
+@permission_required('infra')
+def del_nas(request):
+ nas = DelNasForm(request.POST or None)
+ if nas.is_valid():
+ nas_dels = nas.cleaned_data['nas']
+ for nas_del in nas_dels:
+ try:
+ with transaction.atomic(), reversion.create_revision():
+ nas_del.delete()
+ reversion.set_user(request.user)
+ messages.success(request, "Le nas a été supprimé")
+ except ProtectedError:
+ messages.error(request, "Erreur le Nas suivant %s ne peut être supprimé" % nas_del)
+ return redirect("/machines/index_nas")
+ return form({'machineform': nas, 'interfaceform': None}, 'machines/machine.html', request)
+
@login_required
@permission_required('cableur')
def index(request):
@@ -724,6 +772,12 @@ def index_machinetype(request):
machinetype_list = MachineType.objects.select_related('ip_type').order_by('type')
return render(request, 'machines/index_machinetype.html', {'machinetype_list':machinetype_list})
+@login_required
+@permission_required('cableur')
+def index_nas(request):
+ nas_list = Nas.objects.select_related('machine_type').order_by('name')
+ return render(request, 'machines/index_nas.html', {'nas_list':nas_list})
+
@login_required
@permission_required('cableur')
def index_extension(request):
@@ -830,6 +884,12 @@ def history(request, object, id):
except Vlan.DoesNotExist:
messages.error(request, "Vlan inexistant")
return redirect("/machines/")
+ elif object == 'nas' and request.user.has_perms(('cableur',)):
+ try:
+ object_instance = Nas.objects.get(pk=id)
+ except Nas.DoesNotExist:
+ messages.error(request, "Nas inexistant")
+ return redirect("/machines/")
else:
messages.error(request, "Objet inconnu")
return redirect("/machines/")