diff --git a/preferences/admin.py b/preferences/admin.py
index 05e7ce4a..5ee0bf40 100644
--- a/preferences/admin.py
+++ b/preferences/admin.py
@@ -39,7 +39,8 @@ from .models import (
AssoOption,
MailMessageOption,
HomeOption,
- RadiusKey
+ RadiusKey,
+ SwitchManagementCred
)
@@ -95,6 +96,10 @@ class RadiusKeyAdmin(VersionAdmin):
"""Class radiuskey"""
pass
+class SwitchManagementCredAdmin(VersionAdmin):
+ """Class managementcred for switch"""
+ pass
+
admin.site.register(OptionalUser, OptionalUserAdmin)
admin.site.register(OptionalMachine, OptionalMachineAdmin)
@@ -105,5 +110,6 @@ admin.site.register(Service, ServiceAdmin)
admin.site.register(MailContact, MailContactAdmin)
admin.site.register(Reminder, ReminderAdmin)
admin.site.register(RadiusKey, RadiusKeyAdmin)
+admin.site.register(SwitchManagementCred, SwitchManagementCredAdmin)
admin.site.register(AssoOption, AssoOptionAdmin)
admin.site.register(MailMessageOption, MailMessageOptionAdmin)
diff --git a/preferences/forms.py b/preferences/forms.py
index c983feba..5263c7e5 100644
--- a/preferences/forms.py
+++ b/preferences/forms.py
@@ -39,7 +39,8 @@ from .models import (
Service,
MailContact,
Reminder,
- RadiusKey
+ RadiusKey,
+ SwitchManagementCred
)
from topologie.models import Switch
@@ -260,6 +261,31 @@ class RadiusKeyForm(FormRevMixin, ModelForm):
return instance
+class SwitchManagementCredForm(FormRevMixin, ModelForm):
+ """Edition, ajout de creds de management pour gestion
+ et interface rest des switchs"""
+ members = forms.ModelMultipleChoiceField(
+ Switch.objects.all(),
+ required=False
+ )
+
+ class Meta:
+ model = SwitchManagementCred
+ fields = '__all__'
+
+ def __init__(self, *args, **kwargs):
+ prefix = kwargs.pop('prefix', self.Meta.model.__name__)
+ super(SwitchManagementCredForm, self).__init__(*args, prefix=prefix, **kwargs)
+ instance = kwargs.get('instance', None)
+ if instance:
+ self.initial['members'] = Switch.objects.filter(management_creds=instance)
+
+ def save(self, commit=True):
+ instance = super().save(commit)
+ instance.switch_set = self.cleaned_data['members']
+ return instance
+
+
class MailContactForm(ModelForm):
"""Edition, ajout d'adresse de contact"""
class Meta:
diff --git a/preferences/migrations/0048_switchmanagementcred.py b/preferences/migrations/0048_switchmanagementcred.py
new file mode 100644
index 00000000..9221b115
--- /dev/null
+++ b/preferences/migrations/0048_switchmanagementcred.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2018-07-10 23:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import re2o.aes_field
+import re2o.mixins
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('preferences', '0047_auto_20180711_0015'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='SwitchManagementCred',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('management_id', models.CharField(help_text='Login du switch', max_length=63)),
+ ('management_pass', re2o.aes_field.AESEncryptedField(help_text='Mot de passe', max_length=63)),
+ ('default_switch', models.BooleanField(default=True, help_text='Creds par défaut des switchs', unique=True)),
+ ],
+ options={
+ 'permissions': (('view_switchmanagementcred', 'Peut voir un objet switchmanagementcred'),),
+ },
+ bases=(re2o.mixins.AclMixin, models.Model),
+ ),
+ ]
diff --git a/preferences/models.py b/preferences/models.py
index 391ed21d..12984d8a 100644
--- a/preferences/models.py
+++ b/preferences/models.py
@@ -246,7 +246,7 @@ class OptionalTopologie(AclMixin, PreferencesModel):
def provision_switchs_enabled(self):
"""Return true if all settings are ok : switchs on automatic provision,
ip_type"""
- return bool(self.provisioned_switchs and self.switchs_ip_type)
+ return bool(self.provisioned_switchs and self.switchs_ip_type and SwitchManagementCred.objects.filter(default_switch=True).exists())
class Meta:
permissions = (
@@ -288,6 +288,31 @@ class RadiusKey(AclMixin, models.Model):
return "Clef radius " + str(self.id) + " " + str(self.comment)
+class SwitchManagementCred(AclMixin, models.Model):
+ """Class of a management creds of a switch, for rest management"""
+ management_id = models.CharField(
+ max_length=63,
+ help_text="Login du switch"
+ )
+ management_pass = AESEncryptedField(
+ max_length=63,
+ help_text="Mot de passe"
+ )
+ default_switch = models.BooleanField(
+ default=True,
+ unique=True,
+ help_text= "Creds par défaut des switchs"
+ )
+
+ class Meta:
+ permissions = (
+ ("view_switchmanagementcred", "Peut voir un objet switchmanagementcred"),
+ )
+
+ def __str__(self):
+ return "Identifiant " + str(self.management_id)
+
+
class Reminder(AclMixin, models.Model):
"""Options pour les mails de notification de fin d'adhésion.
Days: liste des nombres de jours pour lesquells un mail est envoyé
diff --git a/preferences/templates/preferences/aff_switchmanagementcred.html b/preferences/templates/preferences/aff_switchmanagementcred.html
new file mode 100644
index 00000000..2f03edf8
--- /dev/null
+++ b/preferences/templates/preferences/aff_switchmanagementcred.html
@@ -0,0 +1,47 @@
+{% 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 %}
+
+
+
+ Identifiant |
+ Creds par default des switchs |
+ |
+ |
+
+
+ {% for switchmanagementcred in switchmanagementcred_list %}
+
+ {{ switchmanagementcred.management_id }} |
+ {{ switchmanagementcred.default_switch }} |
+
+ {% can_edit switchmanagementcred %}
+ {% include 'buttons/edit.html' with href='preferences:edit-switchmanagementcred' id=switchmanagementcred.id %}
+ {% acl_end %}
+ {% include 'buttons/history.html' with href='preferences:history' name='switchmanagementcred' id=switchmanagementcred.id %}
+ |
+
+ {% endfor %}
+
+
diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html
index 36f4a001..59dc5979 100644
--- a/preferences/templates/preferences/display_preferences.html
+++ b/preferences/templates/preferences/display_preferences.html
@@ -115,7 +115,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
- Configuration des switches
+ Clef radius
+ {% can_create RadiusKey%}
+ Ajouter une clef radius
+ {% acl_end %}
+ {% include "preferences/aff_radiuskey.html" with radiuskey_list=radiuskey_list %}
+
+ Configuration des switches
Web management, activé si provision automatique |
@@ -139,11 +145,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
- Clef radius
- {% can_create RadiusKey%}
- Ajouter une clef radius
+ Creds de management des switchs
+ {% can_create SwitchManagementCred%}
+ Ajouter un id/mdp de management switch
{% acl_end %}
- {% include "preferences/aff_radiuskey.html" with radiuskey_list=radiuskey_list %}
+
+
+ {% if switchmanagementcred_list %} OK{% else %}Manquant{% endif %}
+ {% include "preferences/aff_switchmanagementcred.html" with switchmanagementcred_list=switchmanagementcred_list %}
+
+
Préférences generales
diff --git a/preferences/urls.py b/preferences/urls.py
index 6174b7dc..3fdf38b7 100644
--- a/preferences/urls.py
+++ b/preferences/urls.py
@@ -95,6 +95,13 @@ urlpatterns = [
name='edit-radiuskey'
),
url(r'^del_radiuskey/$', views.del_radiuskey, name='del-radiuskey'),
+ url(r'^add_switchmanagementcred/$', views.add_switchmanagementcred, name='add-switchmanagementcred'),
+ url(
+ r'^edit_switchmanagementcred/(?P[0-9]+)$',
+ views.edit_switchmanagementcred,
+ name='edit-switchmanagementcred'
+ ),
+ url(r'^del_switchmanagementcred/$', views.del_switchmanagementcred, name='del-switchmanagementcred'),
url(
r'^history/(?P\w+)/(?P[0-9]+)$',
re2o.views.history,
diff --git a/preferences/views.py b/preferences/views.py
index 69ea27a4..125f67fe 100644
--- a/preferences/views.py
+++ b/preferences/views.py
@@ -46,7 +46,8 @@ from .forms import MailContactForm, DelMailContactForm
from .forms import (
ServiceForm,
ReminderForm,
- RadiusKeyForm
+ RadiusKeyForm,
+ SwitchManagementCredForm
)
from .models import (
Service,
@@ -59,7 +60,8 @@ from .models import (
OptionalTopologie,
HomeOption,
Reminder,
- RadiusKey
+ RadiusKey,
+ SwitchManagementCred
)
from . import models
from . import forms
@@ -92,6 +94,7 @@ def display_options(request):
mailcontact_list = MailContact.objects.all()
reminder_list = Reminder.objects.all()
radiuskey_list = RadiusKey.objects.all()
+ switchmanagementcred_list = SwitchManagementCred.objects.all()
return form({
'useroptions': useroptions,
'machineoptions': format_options(machineoptions),
@@ -104,6 +107,7 @@ def display_options(request):
'reminder_list': reminder_list,
'mailcontact_list': mailcontact_list,
'radiuskey_list' : radiuskey_list,
+ 'switchmanagementcred_list': switchmanagementcred_list,
}, 'preferences/display_preferences.html', request)
@@ -284,6 +288,51 @@ def del_radiuskey(request, radiuskey_instance, **_kwargs):
)
+@login_required
+@can_create(SwitchManagementCred)
+def add_switchmanagementcred(request):
+ """Ajout de creds de management"""
+ switchmanagementcred = SwitchManagementCredForm(request.POST or None)
+ if switchmanagementcred.is_valid():
+ switchmanagementcred.save()
+ messages.success(request, "Ces creds ont été ajoutés")
+ return redirect(reverse('preferences:display-options'))
+ return form(
+ {'preferenceform': switchmanagementcred, 'action_name': 'Ajouter'},
+ 'preferences/preferences.html',
+ request
+ )
+
+@can_edit(SwitchManagementCred)
+def edit_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs):
+ """Edition des creds de management"""
+ switchmanagementcred = SwitchManagementCredForm(request.POST or None, instance=switchmanagementcred_instance)
+ if switchmanagementcred.is_valid():
+ switchmanagementcred.save()
+ messages.success(request, "Creds de managament modifié")
+ return redirect(reverse('preferences:display-options'))
+ return form(
+ {'preferenceform': switchmanagementcred, 'action_name': 'Editer'},
+ 'preferences/preferences.html',
+ request
+ )
+
+
+@login_required
+@can_delete(SwitchManagementCred)
+def del_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs):
+ """Destruction d'un switchmanagementcred"""
+ if request.method == "POST":
+ switchmanagementcred_instance.delete()
+ messages.success(request, "Ce switchmanagementcred a été détruit")
+ return redirect(reverse('preferences:display-options'))
+ return form(
+ {'objet': switchmanagementcred_instance, 'objet_name': 'switchmanagementcred'},
+ 'preferences/delete.html',
+ request
+ )
+
+
@login_required
@can_create(MailContact)
def add_mailcontact(request):
diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py
index c7d153f1..e3d76aca 100644
--- a/re2o/templatetags/acl.py
+++ b/re2o/templatetags/acl.py
@@ -125,6 +125,8 @@ MODEL_NAME = {
'preferences.Reminder': preferences.models.Reminder,
'AssoOption': preferences.models.AssoOption,
'MailMessageOption': preferences.models.MailMessageOption,
+ 'RadiusKey': preferences.models.RadiusKey,
+ 'SwitchManagementCred': preferences.models.SwitchManagementCred,
# topologie
'Stack': topologie.models.Stack,
'Switch': topologie.models.Switch,
diff --git a/re2o/views.py b/re2o/views.py
index 4b7ef0a8..0a321779 100644
--- a/re2o/views.py
+++ b/re2o/views.py
@@ -99,6 +99,7 @@ HISTORY_BIND = {
'mailcontact': preferences.models.MailContact,
'reminder': preferences.models.Reminder,
'radiuskey': preferences.models.RadiusKey,
+ 'switchmanagementcred': preferences.models.SwitchManagementCred,
},
'cotisations': {
'facture': cotisations.models.Facture,
diff --git a/topologie/migrations/0071_switch_management_creds.py b/topologie/migrations/0071_switch_management_creds.py
new file mode 100644
index 00000000..d9eeb774
--- /dev/null
+++ b/topologie/migrations/0071_switch_management_creds.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2018-07-10 23:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('preferences', '0048_switchmanagementcred'),
+ ('topologie', '0070_switch_radius_key'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='switch',
+ name='management_creds',
+ field=models.ForeignKey(blank=True, help_text='Identifiant de management de ce switch', null=True, on_delete=django.db.models.deletion.PROTECT, to='preferences.SwitchManagementCred'),
+ ),
+ ]
diff --git a/topologie/models.py b/topologie/models.py
index d2adea54..01101d1c 100644
--- a/topologie/models.py
+++ b/topologie/models.py
@@ -49,7 +49,11 @@ from django.db import transaction
from django.utils.translation import ugettext_lazy as _
from reversion import revisions as reversion
-from preferences.models import OptionalTopologie, RadiusKey
+from preferences.models import (
+ OptionalTopologie,
+ RadiusKey,
+ SwitchManagementCred
+)
from machines.models import Machine, regen
from re2o.mixins import AclMixin, RevMixin
@@ -228,6 +232,13 @@ class Switch(AclMixin, Machine):
on_delete=models.PROTECT,
help_text="Clef radius du switch"
)
+ management_creds = models.ForeignKey(
+ 'preferences.SwitchManagementCred',
+ blank=True,
+ null=True,
+ on_delete=models.PROTECT,
+ help_text="Identifiant de management de ce switch"
+ )
class Meta:
unique_together = ('stack', 'stack_member_id')
@@ -289,15 +300,30 @@ class Switch(AclMixin, Machine):
@cached_property
def get_radius_key(self):
+ """Retourne l'objet de la clef radius de ce switch"""
return self.radius_key or RadiusKey.objects.filter(default_switch=True).first()
@cached_property
def get_radius_key_value(self):
+ """Retourne la valeur en str de la clef radius, none si il n'y en a pas"""
if self.get_radius_key:
return self.get_radius_key.radius_key
else:
return None
+ @cached_property
+ def get_management_cred(self):
+ """Retourne l'objet des creds de managament de ce switch"""
+ return self.management_creds or SwitchManagementCred.objects.filter(default_switch=True).first()
+
+ @cached_property
+ def get_management_cred_value(self):
+ """Retourne un dict des creds de management du switch"""
+ if self.get_management_cred:
+ return {'id': self.get_management_cred.management_id, 'pass': self.get_management_cred.management_pass}
+ else:
+ return None
+
@cached_property
def rest_enabled(self):
return OptionalTopologie.get_cached_value('switchs_rest_management') or self.automatic_provision